Все разработчики C# знают основы языка. Но лишь немногим известны скрытые возможности, о которых вы узнаете после прочтения этой статьи.
К основам относятся объявления, условия, циклы, операторы и прочее. Часть программистов даже добилась определенных успехов в познании анонимных типов, lambda-выражений, LINQ и универсальных шаблонов. Однако лишь немногие разработчики знают о скрытых возможностях языка, поэтому в этой статье эксперты C# поделились своими фишками.
1. Класс Path
Этот совет не совсем про C#, но он будет полезен любому разработчику. К большому сожалению, лишь некоторые специалисты пользуются System.IO.Path.Combine(). Многие просто не знают и не понимают, как это может облегчить разработку. В действительности, весь класс Path обладает большим потенциалом и возможностями, о которых стоит помнить! В любом создаваемом приложении вы обязательно увидите строку, приведенную ниже, несмотря на то, что такого быть не должно:
string path = dir + "\\" + fileName;
2. Лямбда-выражения
Лямбда-выражения и типовой вывод в языке недооценены. Лямбда могут иметь множество выражений. К тому же они имеют свойство автоматического удваивания так же, как и совместимые объекты делегата (стоит просто посмотреть на сигнатуру). Пример:
Console.CancelKeyPress += (sender, e) => { Console.WriteLine("CTRL+C detected!\n"); e.Cancel = true; };
Следует обратить внимание на то, что в этом фрагменте нет new CancellationEventHandler, и поэтому необходимости указывать типы sender и e тоже нет, так как они возвращаются событием. Именно по этой причине такое решение более предпочтительно при написании всего делегата, который, помимо всего прочего, требует указания типов параметров.
Лямбда-выражения не должны ничего возвращать, и в этом контексте вывод типов становится максимально эффективным.
Однако стоит помнить, что вы всегда можете вернуть лямбда-выражение в контексте функционального программирования. Например, вот лямбда, создающая лямбду, обрабатывающую событие Button.Click:
Func makeHandler = (dx, dy) => (sender, e) => { var btn = (Button) sender; btn.Top += dy; btn.Left += dx; };
btnUp.Click += makeHandler(0, -1); btnDown.Click += makeHandler(0, 1); btnLeft.Click += makeHandler(-1, 0); btnRight.Click += makeHandler(1, 0);
3. Оператор ??
Вы можете связать оператор ??
так, что получится куча нулевых сравнений.
string result = value1 ?? value2 ?? value3 ?? String.Empty;
4. Aliased generics
using ASimpleName = Dictionary<string, Dictionary<string, List>>;
Благодаря этой фиче вы можете использовать ASimpleName
, вместо Dictionary<string, Dictionary<string, List>>
.
Применяйте этот трюк, когда нужны одинаковые длинные и сложные обобщения во многих местах.
5. Нормализация строк
Во время нормализации string настойчиво советуется применять ToUpperInvariant
, а не ToLowerInvariant
,так как в Microsoft провели оптимизацию кода для того чтобы выполнять сравнения в верхнем регистре.
6. Оператор коалесценции
Оператор нулевой коалесценции и скобки для автоматической инициализации коллекций.
private IList _foo;
public IList ListOfFoo
{ get { return _foo ?? (_foo = new List()); } }
7. Избегайте проверки на нулевые обработчики событий
Когда вы добавляете пустой делегат события во время объявления, то избавляете себя от нужды все время проверять событие на null перед тем как его вызвать. Пример:
public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // добавляем пустой delegate!
Позволяет делать вам так:
public void DoSomething()
{
Click(this, "foo");
}
А не так:
public void DoSomething()
{
// Unnecessary!
MyClickHandler click = Click;
if (click != null) // Unnecessary!
{
click(this, "foo");
}
}
8. Неявные обобщения
1) Неявные обобщения (не только для методов, но и для классов):
void GenericMethod<T>( T input ) { ... } //Возвращаемый тип, поэтому GenericMethod
GenericMethod<int>(23); //Вам не нужны GenericMethod(23); //Достаточно этого
2) Простые лямбда-выражения с одним параметром:
x => x.ToString() //упрощает множественный вызов
3)Анонимные типы и инициализаторы:
var colours = new Dictionary {
{ "red", "#ff0000" },
{ "green", "#00ff00" },
{ "blue", "#0000ff" }
};
int[] arrayOfInt = { 1, 2, 3, 4, 5 };
4) Автоматические свойства могут иметь различные области действия:
public int MyId { get; private set; }
5) Псевдоним пространства имен:
using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;
web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();
9. Ключевое слово "as"
Использование ключевого слова "as" приводит этот код
MyClass myObject = (MyClass) obj;
к следующему виду:
MyClass myObject = obj as MyClass;
Во втором случае возвращаемое значение будет null, если obj - это не MyClass, а не бросит исключение класса.
10. Автоматические свойства
Автоматические свойства, которые превращают это:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
в это:
public string Name { get; set;}
Также инициализаторы объектов
Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();
становятся:
Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}
Комментарии