фишки - популярные библиотеки c#




Скрытые особенности C#? (20)

Команда @ сообщает компилятору игнорировать любые escape-символы в строке.

Просто хотел прояснить этот ... он не говорит ему игнорировать escape-символы, он на самом деле говорит компилятору интерпретировать строку как литерал.

Если у вас есть

string s = @"cat
             dog
             fish"

он будет фактически распечатываться как (обратите внимание, что он даже включает пробелы, используемые для отступов):

cat
             dog
             fish

Это пришло мне в голову после того, как я узнал следующее из этого вопроса :

where T : struct

Мы, разработчики C #, все знаем основы C #. Я имею в виду декларации, условные обозначения, циклы, операторы и т. Д.

Некоторые из нас даже освоили такие вещи, как Generics , анонимные типы , lambdas , LINQ , ...

Но каковы самые скрытые возможности или хитрости C #, которые даже поклонники C #, наркоманы, эксперты едва ли знают?

Вот выявленные особенности:


Ключевые слова

Атрибуты

Синтаксис

  • ?? (coalesce nulls) оператор kokos
  • Маркировка номера Ником Берарди
  • where T:new автор Lars Mæhlum
  • Неявные дженерики Keith
  • Однопараметрические лямбды Keith
  • Авто недвижимости by Keith
  • Имена псевдонимов by Keith
  • Вербальные строковые литералы с @ by Patrick
  • значения enum по lfoust
  • marxidad от marxidad
  • операторы event by marxidad
  • Форматировать скобки строки по Portman
  • Модификаторы доступности для доступа к аксессуарам от xanadont
  • Условный (тройной) оператор ( ?: JasonS
  • checked и unchecked операторы Binoj Antony
  • implicit and explicit операторы Flory

Особенности языка

Возможности Visual Studio

  • Выберите блок текста в редакторе Himadri
  • Фрагменты от DannySmurf

Фреймворк

Методы и свойства

Советы и хитрости

  • Хороший метод для обработчиков событий Andreas HR Nilsson
  • Сравнение сверху с John
  • Доступ к анонимным типам без отражения dp
  • Быстрый способ ленивого создания свойств коллекции Will
  • JavaScript-подобные анонимные встроенные функции roosteronacid

Другой


С CLR через C # :

При нормализации строк настоятельно рекомендуется использовать ToUpperInvariant вместо ToLowerInvariant, потому что Microsoft оптимизировала код для выполнения сравнений в верхнем регистре .

Я помню, как однажды мой коллега всегда менял строки в верхний регистр, прежде чем сравнивать. Я всегда задавался вопросом, почему он это делает, потому что я считаю, что более естественным является преобразование в нижний регистр. Прочитав книгу, я знаю почему.


  1. ?? - коалесцирующий оператор
  2. using ( statement / directive ) - отличное ключевое слово, которое можно использовать не только для вызова Dispose
  3. readonly - следует использовать больше
  4. netmodules - слишком плохо, что в Visual Studio нет поддержки

« yield » придет мне на ум. Некоторые из атрибутов, таких как DefaultValueAttribute , также относятся к моим фаворитам.

Ключевое слово « var » немного известно, но вы также можете использовать его в приложениях .NET 2.0 (пока вы используете компилятор .NET 3.5 и устанавливаете его для вывода кода 2.0), похоже, не известно Что ж.

Редактировать: kokos, спасибо, что указал? оператора, это действительно действительно полезно. Так как это немного сложно для Google (так как это просто игнорируется), вот страница документации MSDN для этого оператора: ?? ??


Вот некоторые интересные скрытые функции C # в виде недокументированных ключевых слов C #:

__makeref

__reftype

__refvalue

__arglist

Это недокументированные ключевые слова C # (даже Visual Studio их распознает!), Которые были добавлены для более эффективного бокса / распаковки перед дженериками. Они работают в координации с структурой System.TypedReference.

Существует также __arglist, который используется для списков параметров переменной длины.

Одна вещь, о которой люди мало знают, это System.WeakReference - очень полезный класс, который отслеживает объект, но все же позволяет сборщику мусора собирать его.

Самой полезной «скрытой» функцией будет ключевое слово yield yield. Это действительно не скрыто, но многие люди об этом не знают. LINQ построен поверх этого; он позволяет выполнять запросы с задержкой, создавая конечный автомат под капотом. Раймонд Чен недавно опубликовал информацию о внутренних подробных деталях .


Все остальное, плюс

1) неявные дженерики (почему только по методам, а не по классам?)

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2) простые лямбды с одним параметром:

x => x.ToString() //simplify so many calls

3) анонимные типы и инициализаторы:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

Другой:

4) Авто свойства могут иметь разные области применения:

public int MyId { get; private set; }

Спасибо @pzycoman за то, что напомнили мне:

5) Имена псевдонимов (не то, что вам, вероятно, понадобится это особое различие):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

Если вы хотите выйти из своей программы, не вызывая никаких окончательных блоков или финализаторов, используйте FailFast :

Environment.FailFast()

Использование @ для имен переменных, которые являются ключевыми словами.

var @object = new object();
var @string = "";
var @if = IpsoFacto(); 

Мой любимый трюк - использовать оператор null collosece и круглые скобки для автоматического создания экземпляров для меня.

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }

От Рика Стралла :

Вы можете связать ?? чтобы вы могли выполнить кучу нулевых сравнений.

string result = value1 ?? value2 ?? value3 ?? String.Empty;

Это не C # per se, но я не видел никого, кто действительно использует System.IO.Path.Combine() в той степени, в которой они должны. На самом деле весь класс Path действительно полезен, но никто его не использует!

Я готов поспорить, что каждое производственное приложение имеет следующий код, хотя он не должен:

string path = dir + "\\" + fileName;

Я не знал ключевое слово «как» довольно долгое время.

MyClass myObject = (MyClass) obj;

против

MyClass myObject = obj as MyClass;

Второй возвращает значение null, если obj не является MyClass, а не бросает исключение класса.


Я, как правило, обнаружил, что большинство разработчиков C # не знают о типах «nullable». В принципе, примитивы, которые могут иметь нулевое значение.

double? num1 = null; 
double num2 = num1 ?? -100;

Установите значение nullable double, num1 , null, затем установите регулярные двойные, num2 , num1 или -100, если num1 был null.

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

еще одна вещь о Nullable типе:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

это возвращает String.Empty. Проверьте this ссылку для получения более подробной информации.


Unions (тип разделяемой памяти C ++) в чистом, безопасном C #

Не прибегая к небезопасному режиму и указателям, вы можете иметь членов класса, разделяющих пространство памяти в классе / структуре. Учитывая следующий класс:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

Вы можете изменять значения байтовых полей, манипулируя полем Int32 и наоборот. Например, эта программа:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

Вывод:

2147483647
FF FF FF 7F
65535

просто добавьте использование System.Runtime.InteropServices;


Избегайте проверки нулевых обработчиков событий

Добавление пустого делегата в события в объявлении, подавляющее необходимость всегда проверять событие для null перед вызовом, является удивительным. Пример:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

Позвольте вам сделать это

public void DoSomething()
{
    Click(this, "foo");
}

Вместо этого

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

Также см. Эту связанную дискуссию и эту запись в блоге Эрика Липперта по этой теме (и возможные недостатки).


Возврат анонимных типов из метода и доступ к членам без отражения.

// Useful? probably not.
private void foo()
{
    var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
    Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
    return new { Name = "dp", Badges = 5 };
}    

// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
   return (T) obj;
}

Вот полезный для регулярных выражений и путей к файлам:

"c:\\program files\\oldway"
@"c:\program file\newway"

Команда @ сообщает компилятору игнорировать любые escape-символы в строке.


Если вы пытаетесь использовать фигурные скобки внутри выражения String.Format ...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

@Ed, я немного сдержанно рассказываю об этом, поскольку это немного больше, чем придираться. Однако я хотел бы указать, что в вашем примере кода:

MyClass c;
  if (obj is MyClass)
    c = obj as MyClass

Если вы собираетесь использовать «есть», зачем следить за ним с помощью безопасного броска, используя «как»? Если вы установили, что obj действительно MyClass, стандартное исполнение болота:

c = (MyClass)obj

... никогда не потерпит неудачу.

Точно так же вы можете просто сказать:

MyClass c = obj as MyClass;
if(c != null)
{
   ...
}

Я не знаю достаточно о внутренностях .NET, чтобы убедиться, но мои инстинкты говорят мне, что это сократит максимум до двух типов операций приведения до максимум одного. Едва ли это может сломать банк обработки в любом случае; лично, я думаю, что последняя форма выглядит более чистой.


Примеси. В принципе, если вы хотите добавить функцию к нескольким классам, но не можете использовать один базовый класс для всех из них, получите каждый класс для реализации интерфейса (без участников). Затем напишите метод расширения для интерфейса , т. Е.

public static DeepCopy(this IPrototype p) { ... }

Конечно, некоторая ясность приносится в жертву. Но это работает!





hidden-features