10 полезных вещей в C#, которые облегчат вам жизнь

Если вы начинаете знакомство с С# или хотите расширить свои познания, вам стоит изучить эти полезные особенности языка, которые помогут вам упростить код, избежать ошибок и сэкономить кучу времени.

async или await

Используйте возможности асинхронного программирования для того, чтобы разблокировать возможности одного потока, пока ожидается завершение другого. Например: если происходит медленный веб-запрос, то при синхронных программировании незанятый поток будет простаивать, пока веб-запрос не будет выполнен. Асинхронное программирование при помощи модификатора async позволяет избежать этого. Также полезным является использование async вместе с оператором await, который приостанавливает выполнение потока, пока не произойдет ожидаемое событие. Более подробно вы можете прочитать здесь.

Инициализаторы объектов, массивов и коллекций

Намного проще создавать экземпляры классов, массивы и коллекции при помощи специальных инициализаторов:

//Just some demo class
public class Employee {
    public string Name {get; set;}
    public DateTime StartDate {get; set;}
}

//Create an employlee by using the initializer
Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()};

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

Лямбда-выражения, делегаты и замыкания

Они бывают необходимы в самых разнообразных случаях, но самую большую пользу они приносят при работе с LINQ. Узнайте о них побольше тут.

Оператор объединения со значением null

?? — довольно простой, но очень полезный оператор для определенных ситуаций. ?? возвращает левый операнд, если он не NULL, иначе он вернет правый операнд:

//May be null
var someValue = service.GetValue();

var defaultValue = 23

//result will be 23 if someValue is null
var result = someValue ?? defaultValue;

Также его можно использовать с тремя операндами, в этом случае проверка на NULL будет происходить слева направо:

string anybody = parm1 ?? localDefault ?? globalDefault;

А еще можно избежать многих ошибок, преобразовывая NULL в какое-либо конкретное значение:

var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);

Более подробно об операторе узнаете здесь.

Интерполированные строки $”{x}”

Новые возможности C# 6 позволяют вам интерполировать (разбивать) строки простым и элегантным путем:

//Old way
var someString = String.Format("Some data: {0}, some more data: {1}", 
someVariable, someOtherVariable);

//NewWay
var someString = $"Some data: {someVariable}, 
some more data: {someOtherVariable}";

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

Оператор безопасной навигации

Вот пример работы с оператором:

//Null if customer or customer.profile or customer.profile.age is null
var currentAge = customer?.profile?.age;

Если какой-либо из операндов будет равен NULL, то возвращенное значение тоже будет NULL. Неплохой способ проверять переменные на отсутствие объявления. Подробности тут.

Выражение nameof

На первый взгляд использование nameof не является столь уж нужным, однако на самом же деле nameof весьма полезен, когда вы используете автоматические инструменты рефакторинга, вроде ReSharper, и тогда вам нужно обращаться к аргументу метода по его имени.

public void PrintUserName(User currentUser)
{
    //The refactoring tool might miss the textual reference to current user below
    //if we're renaming it
    if(currentUser == null)
        _logger.Error("Argument currentUser is not provided");

    //...
}

Но при использовании автоматического рефакторинга лучше реализовать тот же код следующим образом:

public void PrintUserName(User currentUser)
{
    //The refactoring tool will not miss this...
    if(currentUser == null)
        _logger.Error($"Argument {nameof(currentUser)} is not provided");

    //...
}

Больше информации здесь.

Инициализаторы свойств

Инициализаторы свойств позволяют вам объявить начальное значение свойства:

public class User
{ 
    public Guid Id { get; } = Guid.NewGuid();  
    // ...
}

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

Операторы as и is

Оператор is используется для того, чтобы определить принадлежность объекта к типу, если это так, то вернет true. Например, является ли объект Person экземпляром типа Adult или типа, производного от Adult:

if (Person is Adult)
{
    //do stuff
}

Для проверки возможности преобразования типов используйте оператор as:

SomeType y = x as SomeType;
if (y != null)
{
    //do stuff
}

Если преобразование невозможно, то будет возвращено значение NULL.

Ключевое слово yield

Если используется ключевое слово yield в инструкции, то это означает, что обычный метод, метод доступа get или оператор, в котором оно встречается, является итератором. В следующем примере метод будет возвращать по порядку степени двойки: 2, 4, 8, 16, 32, 64, 128, 256.

public static IEnumerable<int> Power(int number, int exponent)
{
    int result = 1;
    for (int i = 0; i < exponent; i++)
    {
      result = result * number;
      yield return result;
    }
}

Ключевое слово yield позволяет избежать создания явного дополнительного класса, в котором содержится состояние перечисления. Отличный и простой способ создания последовательности объектов. Более подробно ознакомьтесь здесь.

Источник: CodeAddiction