HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Знание этих приёмов позволит вам избежать многих ошибок. Вы не только станете писать более понятный код, но и сэкономите своё время.</p>
1 <p>Знание этих приёмов позволит вам избежать многих ошибок. Вы не только станете писать более понятный код, но и сэкономите своё время.</p>
2 <h2>1. async/await</h2>
2 <h2>1. async/await</h2>
3 <p>Паттерны<strong>async/await</strong>позволят разблокировать UI/текущий поток при выполнении блочных операторов. Также они позволят вашему коду работать даже в том случае, если что-то будет блокировать его выполнение (к примеру, web-запрос).</p>
3 <p>Паттерны<strong>async/await</strong>позволят разблокировать UI/текущий поток при выполнении блочных операторов. Также они позволят вашему коду работать даже в том случае, если что-то будет блокировать его выполнение (к примеру, web-запрос).</p>
4 <p>Подробности использования этих паттернов вы найдёте<a>здесь</a>.</p>
4 <p>Подробности использования этих паттернов вы найдёте<a>здесь</a>.</p>
5 <h2>2. Инициализаторы объектов/коллекций/массивов</h2>
5 <h2>2. Инициализаторы объектов/коллекций/массивов</h2>
6 <p>Обратите внимание на следующий участок кода:</p>
6 <p>Обратите внимание на следующий участок кода:</p>
7 //Обычный демо-класс public class Employee { public string Name {get; set;} public DateTime StartDate {get; set;} } //Создайте employlee, применяя инициализатор Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()};<p>Этот пример будет вам полезен в юнит-тестировании. В других случаях желательно применять конструкторы.</p>
7 //Обычный демо-класс public class Employee { public string Name {get; set;} public DateTime StartDate {get; set;} } //Создайте employlee, применяя инициализатор Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()};<p>Этот пример будет вам полезен в юнит-тестировании. В других случаях желательно применять конструкторы.</p>
8 <p><a>Подробности</a>.</p>
8 <p><a>Подробности</a>.</p>
9 <h2>3. Лямбды, делегаты, предикаты и замыкания</h2>
9 <h2>3. Лямбды, делегаты, предикаты и замыкания</h2>
10 <p>Просто незаменимы во множестве ситуаций, к примеру, при использовании LINQ. Но вы должны понимать, как и когда их использовать.</p>
10 <p>Просто незаменимы во множестве ситуаций, к примеру, при использовании LINQ. Но вы должны понимать, как и когда их использовать.</p>
11 <p><a>Подробности</a>.</p>
11 <p><a>Подробности</a>.</p>
12 <h2>4. ?? (оператор объединения с NULL)</h2>
12 <h2>4. ?? (оператор объединения с NULL)</h2>
13 <p>x ?? y - возвращает x, когда значение отличается от null; в обратном случае возвращает y.</p>
13 <p>x ?? y - возвращает x, когда значение отличается от null; в обратном случае возвращает y.</p>
14 //Может быть null var someValue = service.GetValue(); var defaultValue = 23 //result будет 23, если someValue - null var result = someValue ?? defaultValue;<p>Операторов ?? может быть несколько:</p>
14 //Может быть null var someValue = service.GetValue(); var defaultValue = 23 //result будет 23, если someValue - null var result = someValue ?? defaultValue;<p>Операторов ?? может быть несколько:</p>
15 string anybody = parm1 ?? localDefault ?? globalDefault;<p>Оператор ?? также подходит для перевода типов null в не null:</p>
15 string anybody = parm1 ?? localDefault ?? globalDefault;<p>Оператор ?? также подходит для перевода типов null в не null:</p>
16 var totalPurchased = PurchaseQuantities.Sum(kvp =&gt; kvp.Value ?? 0);<p><a>Подробности</a>.</p>
16 var totalPurchased = PurchaseQuantities.Sum(kvp =&gt; kvp.Value ?? 0);<p><a>Подробности</a>.</p>
17 <h2>5. $”{x}” (интерполяция строк) - C# 6</h2>
17 <h2>5. $”{x}” (интерполяция строк) - C# 6</h2>
18 <p>Данная фича в C# 6 позволит вам собирать строки элегантно и эффективно:</p>
18 <p>Данная фича в C# 6 позволит вам собирать строки элегантно и эффективно:</p>
19 //Ранее var someString = String.Format("Some data: {0}, some more data: {1}", someVariable, someOtherVariable); //Сейчас var someString = $"Some data: {someVariable}, some more data: {someOtherVariable}";<h2>6. ?.(определяет null) - C# 6</h2>
19 //Ранее var someString = String.Format("Some data: {0}, some more data: {1}", someVariable, someOtherVariable); //Сейчас var someString = $"Some data: {someVariable}, some more data: {someOtherVariable}";<h2>6. ?.(определяет null) - C# 6</h2>
20 <p>x?.y - доступ к членам, который определяется условием null. Значение null возвращается, если левый операнд имеет значение null.</p>
20 <p>x?.y - доступ к членам, который определяется условием null. Значение null возвращается, если левый операнд имеет значение null.</p>
21 //Null, если customer, или customer.profile, или customer.profile.age - null var currentAge = customer?.profile?.age;<p>А значит, больше никаких<strong>NullReferenceExceptions</strong>!</p>
21 //Null, если customer, или customer.profile, или customer.profile.age - null var currentAge = customer?.profile?.age;<p>А значит, больше никаких<strong>NullReferenceExceptions</strong>!</p>
22 <p><a>Подробности</a>.</p>
22 <p><a>Подробности</a>.</p>
23 <h2>7. Выражение nameof - C# 6</h2>
23 <h2>7. Выражение nameof - C# 6</h2>
24 <p>Некоторые скажут, что выражение nameof не очень-то полезно, однако это не так. В случае применения автоматических инструментов рефакторинга (к примеру, ReSharper) нам может потребоваться обращение к аргументу метода по его имени:</p>
24 <p>Некоторые скажут, что выражение nameof не очень-то полезно, однако это не так. В случае применения автоматических инструментов рефакторинга (к примеру, ReSharper) нам может потребоваться обращение к аргументу метода по его имени:</p>
25 public void PrintUserName(User currentUser) { //Инструмент рефакторинга может пропустить текстовое обращение к текущему пользователю, если его переименовать if(currentUser == null) _logger.Error("Argument currentUser is not provided"); //... }<p>Вот, как это должно быть:</p>
25 public void PrintUserName(User currentUser) { //Инструмент рефакторинга может пропустить текстовое обращение к текущему пользователю, если его переименовать if(currentUser == null) _logger.Error("Argument currentUser is not provided"); //... }<p>Вот, как это должно быть:</p>
26 public void PrintUserName(User currentUser) { //Инструмент рефакторинга уже ничего не пропустит if(currentUser == null) _logger.Error($"Argument {nameof(currentUser)} is not provided"); //... }<p><a>Подробности</a>.</p>
26 public void PrintUserName(User currentUser) { //Инструмент рефакторинга уже ничего не пропустит if(currentUser == null) _logger.Error($"Argument {nameof(currentUser)} is not provided"); //... }<p><a>Подробности</a>.</p>
27 <h2>8. Инициализаторы свойств (property) - C# 6</h2>
27 <h2>8. Инициализаторы свойств (property) - C# 6</h2>
28 <p>Позволяют задавать для свойств начальные значения:</p>
28 <p>Позволяют задавать для свойств начальные значения:</p>
29 public class User { public Guid Id { get; } = Guid.NewGuid(); // ... }<p>Их польза в том, что вы не сможете объявить setter, сделав тем самым свойства неизменяемыми. Кроме того, инициализаторы свойств прекрасно работают в связке с синтаксисом первичного конструктора в C# 6.</p>
29 public class User { public Guid Id { get; } = Guid.NewGuid(); // ... }<p>Их польза в том, что вы не сможете объявить setter, сделав тем самым свойства неизменяемыми. Кроме того, инициализаторы свойств прекрасно работают в связке с синтаксисом первичного конструктора в C# 6.</p>
30 <h2>9. Операторы is и as</h2>
30 <h2>9. Операторы is и as</h2>
31 <p>Is - совместимость типов. Оператор возвращает значение true, когда вычисленный левый операнд можно привести к типу, указанному в правом операнде (статический тип).</p>
31 <p>Is - совместимость типов. Оператор возвращает значение true, когда вычисленный левый операнд можно привести к типу, указанному в правом операнде (статический тип).</p>
32 if (Person is Adult) { //код }<p>As - преобразование типов. Оператор возвращает левый операнд, который приведён к типу, заданному правым операндом (статический тип). Однако as возвращает null там, где (T)x вызывает исключение.</p>
32 if (Person is Adult) { //код }<p>As - преобразование типов. Оператор возвращает левый операнд, который приведён к типу, заданному правым операндом (статический тип). Однако as возвращает null там, где (T)x вызывает исключение.</p>
33 SomeType y = x as SomeType; if (y != null) { //код }<h2>10. Ключевое слово yield</h2>
33 SomeType y = x as SomeType; if (y != null) { //код }<h2>10. Ключевое слово yield</h2>
34 <p>Мы уже<a>писали о ключевом слове yield</a>. Оно обеспечивает заполнение интерфейса IEnumerable объектами (items). Давайте посмотрим на код, который вернёт все степени двойки от 2 до 2 в степени 8 (2, 4, 8, 16, 32, 128, 256):</p>
34 <p>Мы уже<a>писали о ключевом слове yield</a>. Оно обеспечивает заполнение интерфейса IEnumerable объектами (items). Давайте посмотрим на код, который вернёт все степени двойки от 2 до 2 в степени 8 (2, 4, 8, 16, 32, 128, 256):</p>
35 public static IEnumerable Power(int number, int exponent) { int result = 1; for (int i = 0; i &lt; exponent; i++) { result = result * number; yield return result; } }<p>Собственно говоря, в умелых руках yield - мощная штука. Вы сможете легко сгенерировать последовательность объектов, то есть системе не потребуется перечислять всю коллекцию целиком, так как это может быть выполнено по требованию.</p>
35 public static IEnumerable Power(int number, int exponent) { int result = 1; for (int i = 0; i &lt; exponent; i++) { result = result * number; yield return result; } }<p>Собственно говоря, в умелых руках yield - мощная штука. Вы сможете легко сгенерировать последовательность объектов, то есть системе не потребуется перечислять всю коллекцию целиком, так как это может быть выполнено по требованию.</p>
36 <p><em>При написании статьи использовались материалы<a>How Not To Code</a>.</em></p>
36 <p><em>При написании статьи использовались материалы<a>How Not To Code</a>.</em></p>
37  
37