Если вы только начали изучение C# или же решили расширить свои знания, мы нашли для вас 10 фич, знание которых позволит вам избежать ошибок, писать более понятный код и сохранить кучу времени.
1. async / await
Использование паттернов async / await позволяет разблокировать UI / текущий поток во время выполнения блочных операторов. Паттерны async / await позволяют коду продолжить выполнение, даже если что-то блокирует его выполнение (например, веб-запрос).
2. Инициализаторы объектов / массивов / коллекций
|
1
2
3
4
5
6
7
8
|
//Обычный демо-класс
publicclassEmployee{
publicstringName{get;set;}
publicDateTimeStartDate{get;set;}
}
//Создайте employlee, используя инициализатор
Employee emp=newEmployee{Name="John Smith",StartDate=DateTime.Now()};
|
Данный пример может быть особенно полезен в юнит-тестировании, но в других случаях лучше использовать конструкторы.
3. Лямбды, предикаты, делегаты и замыкания
Эти фичи просто незаменимы во многих случаях: например, при использовании LINQ. Поэтому рекомендуем вам убедиться, что вы действительно понимаете, когда и как их использовать.
4. ?? (Оператор объединения с NULL)
x ?? y — возвращает x, если значение отличается от null; в противном случае возвращает y.
|
1
2
3
4
5
6
|
//Может быть null
varsomeValue=service.GetValue();
vardefaultValue=23
//result будет 23, если someValue - null
varresult=someValue??defaultValue;
|
Может быть несколько операторов ??:
|
1
|
stringanybody=parm1??localDefault??globalDefault;
|
?? также может быть использован для перевода типов null в не null:
|
1
|
vartotalPurchased=PurchaseQuantities.Sum(kvp=>kvp.Value??0);
|
5. $"{x}" (Интерполяция строк) — C# 6
Фича в C# 6 позволяет эффективно и элегантно собирать строки:
|
1
2
3
4
5
|
//Раньше
varsomeString=String.Format("Some data: {0}, some more data: {1}",someVariable,someOtherVariable);
//Сейчас
varsomeString=$"Some data: {someVariable}, some more data: {someOtherVariable}";
|
6. ?.(определяет null) — C# 6
x?.y — доступ к членам, определяемый условием null. Возвращает значение null, если левый операнд имеет значение null.
|
1
2
|
//Null, если customer, или customer.profile, или customer.profile.age - null
varcurrentAge=customer?.profile?.age;
|
Больше никаких NullReferenceExceptions!
7. Выражение nameof — C# 6
Может показаться, что выражение nameof не особо полезно, но это не так. При использовании автоматических инструментов рефакторинга (например, ReSharper) иногда может потребоваться обратиться к аргументу метода по его имени:
|
1
2
3
4
5
6
7
8
9
|
publicvoidPrintUserName(User currentUser)
{
//Инструмент рефакторинга может пропустить текстовое обращение к текущему пользователю,
еслиегопереименовать
if(currentUser==null)
_logger.Error("Argument currentUser is not provided");
//...
}
|
Вот, как это должно быть:
|
1
2
3
4
5
6
7
8
|
publicvoidPrintUserName(User currentUser)
{
//Инструмент рефакторинга уже ничего не пропустит
if(currentUser==null)
_logger.Error($"Argument {nameof(currentUser)} is not provided");
//...
}
|
8. Инициализаторы свойств (property) — C# 6
Инициализаторы свойств позволяют задавать начальные значения для свойств:
|
1
2
3
4
5
|
publicclassUser
{
publicGuidId{get;}=Guid.NewGuid();
// ...
}
|
Польза их использования заключается в том, что вы не можете объявить setter, тем самым делая свойства неизменяемыми. Инициализаторы свойств хорошо работают в связке с синтаксисом первичного конструктора в C# 6.
9. Операторы as и is
Is — совместимость типов. Возвращает значение true, если вычисленный левый операнд может быть приведен к типу, указанному в правом операнде (статический тип).
|
1
2
3
4
|
if(Person isAdult)
{
//код
}
|
As — преобразование типов. Возвращает левый операнд, приведенный к типу, заданному правым операндом (статический тип), но as возвращает null, где (T)xвызывает исключение.
|
1
2
3
4
5
|
SomeTypey=xasSomeType;
if(y!=null)
{
//код
}
|
10. Ключевое слово yield
Ключевое слово yield позволяет заполнить интерфейс IEnumerable объектами (items). Следующий пример вернет все степени двойки от 2 до 2 в степени 8 (то есть 2, 4, 8, 16, 32, 128, 256):
|
1
2
3
4
5
6
7
8
9
|
publicstaticIEnumerable Power(intnumber,intexponent)
{
intresult=1;
for(inti=0;i<exponent;i++)
{
result=result*number;
yield returnresult;
}
}
|
В правильных руках yield — очень мощная вещь. Оно позволяет с легкостью генерировать последовательность объектов, то есть системе не придется перечислять всю коллекцию целиком — это может быть сделано по требованию.
