Pull to refresh

«Скрытые» полезности С#

Reading time8 min
Views8.3K
Предлагаю мой вольный перевод вопроса с stackoverflow, который мне показался полезным и сидит в фаворитах. Что-то я взял с MSDN (в основном вырезки из русской редакции), что-то -с блогов.
Все мы, С# разработчики, знаем базовые комманды C#. Я имею ввиду объявления, условия, циклы, операторы и т.д.
Некоторые из нас знают даже про Generics, anonymous types, lambdas, linq,…

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

Keywords


yield by Michael Stum Используется в блоке итератора для предоставления значения объекта перечислителя или для сообщения о конце итерации
yield return <expression>;yield break;

var by Michael Stum. Объявляет переменную
var index;

using() statement by kokos.Предоставляет удобный синтаксис, обеспечивающий правильное использование объектов IDisposable.
using (System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\Users\Public\Documents\test.txt"))
{
string s = null;
while((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}

readonly by kokos.Ключевое слово readonly — это модификатор, который можно использовать для полей. Если объявление поля содержит модификатор readonly, присвоение значений таким полям может происходить только как часть объявления или в конструкторе в том же классе.
class Age
{
readonly int _year;
Age(int year)
{
_year = year;
}
void ChangeYear()
{
//_year = 1967; // Compile error if uncommented.
}
}

as by Mike Stone

as / is by Ed Swangren

as / is (improved) by Rocketpants

default by deathofrats

global:: by pzycoman.Когда контекстно-зависимое ключевое слово global предшествует оператору, оно относится к глобальному пространству имен, которое является пространством имен по умолчанию для любой программы C# и, в ином случае, не именуется.
class TestClass : global::TestApp { }

volatile by Jakub Šturc.Ключевое слово volatile указывает, что поле может быть изменено несколькими потоками, выполняющимися одновременно. Поля, объявленные как volatile, не проходят оптимизацию компилятором, которая предусматривает доступ посредством отдельного потока. Это гарантирует наличие наиболее актуального значения в поле в любое время.
class VolatileTest
{
public volatile int i;


public void Test(int _i)
{
i = _i;
}
}

extern alias by Jakub Šturc.В некоторых случаях может потребоваться задать ссылки на две версии сборок с одинаковыми полными именами типов. Например, вам необходимо использовать две или более версий сборки в одном приложении. С помощью внешнего псевдонима сборки можно включить пространства имен для каждой сборки в оболочку внутри пространств имен корневого уровня, именуемых по этому псевдониму, что позволяет использовать их в одном файле.
/r:GridV1=grid.dll
/r:GridV2=grid20.dll
Здесь создаются внешние псевдонимы GridV1 и GridV2. Чтобы использовать эти псевдонимы в программе, создайте на них ссылку с помощью ключевого слова extern. Пример.
extern alias GridV1;
extern alias GridV2;
GridV1::Grid — это элемент управления Grid из grid.dll, а GridV2::Grid — это элемент управления Grid из grid20.dll.

Attributes


DefaultValue by Michael Stum.Аттрибут для задания значения по умолчанию параметра.

ObsoleteAttribute by DannySmurf.Отмечает элементы программы, которые больше не используются.

DebuggerDisplayAttribute by Stu.Определяет способ отображения класса или поля в окнах переменных отладчика.

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

DebuggerStepThrough by bdukes. Задает класс DebuggerStepThroughAttribute. Этот класс не может быть наследован.

ThreadStaticAttribute by marxidad.Указывает, что значение статического поля уникально для каждого потока.

FlagsAttribute by Martin Clarke.Указывает, что перечисление может обрабатываться как битовое поле, которое является набором флагов.
[SerializableAttribute]
[AttributeUsageAttribute(AttributeTargets.Enum, Inherited = false)]
[ComVisibleAttribute(true)]
public class FlagsAttribute : Attribute

ConditionalAttribute by AndrewBurns

Syntax


?? operator by kokos.Оператор ?? называется оператором, поддерживающим значение NULL, и используется для определения значения по умолчанию для нулевых типов значений, а также для ссылочных типов. Он возвращает левый операнд, если он не имеет значения NULL, в противном случае возвращает правый операнд.
class NullCoalesce
{
static int? GetNullableInt()
{
return null;
}


static string GetStringValue()
{
return null;
}

static void Main()
{
// ?? operator example.
int? x = null;

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;

// Assign i to return value of method, unless
// return value is null, in which case assign
// default value of int to i.

int i = GetNullableInt() ?? default(int);

string s = GetStringValue();
// ?? also works with reference types.
// Display contents of s, unless s is null,
// in which case display «Unspecified».

Console.WriteLine(s ?? «Unspecified»);
}
}

number flaggings by Nick Berardi
Decimal = M
Float = F
Double = D


// for example
double d = 30D;

one-parameter lambdas by Keith
x => x.ToString() //simplify so many calls

auto properties by Keith
Public int MyId { get; private set; }

namespace aliases by Keith
using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;


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

verbatim string literals with @ by Patrick
"c:\\program files\\oldway"
@"c:\program file\newway"

(символ @ помогает исключить спец символы)

enum values by lfoust.Enum не обязательно должны иметь значения int.
public enum MyEnum : long
{
Val1 = 1,
Val2 = 2
}

Любое numeric значение можно привести к enum:
MyEnum e = (MyEnum)123;

event operators by marxidad.Используйте ключевое слово event для объявления события в классе издателя.
public class SampleEventArgs
{
public SampleEventArgs(string s) { Text = s; }
public String Text {get; private set;} // readonly
}
public class Publisher
{
// Declare the delegate (if using non-generic pattern).
public delegate void SampleEventHandler(object sender, SampleEventArgs e);


// Declare the event.
public event SampleEventHandler SampleEvent;

// Wrap the event in a protected virtual method
// to enable derived classes to raise the event.
protected virtual void RaiseSampleEvent()
{
// Raise the event by using the () operator.
SampleEvent(this, new SampleEventArgs(«Hello»));
}
}

format string brackets by Portman

property accessor accessibility modifiers by xanadont

ternary operator (:?) by JasonS. condition? first_expression: second_expression;

checked and unchecked operator by Binoj Antony

Language Features


Nullable types by Brad Barker.Тип, допускающие значения NULL, являются экземплярами структуры System.Nullable(T). Тип, допускающий значения NULL, может представлять правильный диапазон значений для своего базового типа значений и дополнительное пустое значение null. Например, для Nullable, называемого «тип Int32, допускающий значения NULL», можно назначить любое значение от -2 147 483 648 до 2 147 483 647 или значение null.
Используйте оператор ??, чтобы назначить значение по умолчанию, применяемое, когда тип, допускающий значения NULL, с текущим значением null, назначен типу, не допускающему значения NULL, например, int? x = null; int y = x ?? -1;

Currying by Brian Leahy

anonymous types by Keith.Анонимные типы предлагают удобный способ инкапсулирования набора свойств только для чтения в один объект без необходимости предварительного явного определения типа. Имя типа создается компилятором и недоступно на уровне исходного кода. Тип свойств выводится компилятором. В следующем примере показан анонимный тип, который инициализируется двумя свойствами: Amount и Message.
var v = new { Amount = 108, Message = "Hello" };

__makeref __reftype __refvalue by Judah Himango

object initializers by lomaxx.Одна из новинок С#3.0… Позволяет делать такие подмены:
Person p = new Person() {FirstName="John",LastName="Doe",Phone="602-123-1234",City="Phoenix"};

То есть определять свойства, не используя конструктор.

Extension Methods by marxidad.Метода расширения позволяют «добавлять» методы в существующие типы без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Методы расширения являются особым видом статического метода, но они вызываются, как если бы они были методами экземпляра в расширенном типе. Для клиентского кода, написанного на языках C# и Visual Basic, нет видимого различия между вызовом метода расширения и вызовом методов, фактически определенных в типе.
class ExtensionMethods2
{


static void Main()
{
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g);
foreach (var i in result)
{
System.Console.Write(i + " ");
}
}
}
//Output: 10 15 21 26 39 45

partial methods by Jon Erickson.Имеется возможность разделить определение класса или структуры, интерфейса или метода между двумя или более исходными файлами. Каждый исходный файл содержит определение типа или метода, и все части объединяются при компиляции приложения.
public partial class Employee
{
public void DoWork()
{
}
}


public partial class Employee
{
public void GoToLunch()
{
}
}

Директивы препроцессора C# by John Asbeck

DEBUG pre-processor directive by Robert Durgin #if debug -код определенный в таком блоке будет выполнен только во время дебага. Удобно при разработке делать более подробные выводы исключений.

Перегрузки операторов by SefBkn.

boolean operators taken to next level by Rob Gough

Visual Studio Features


snippets by DannySmurf.Среда разработки Visual Studio включает функцию, называемую «фрагменты кода». Фрагменты кода — это готовые фрагменты кода, которые можно быстро вставлять в свой код. Например, фрагмент кода for создает пустой цикл for. Некоторые фрагменты кода являются окружающими, т.е. позволяют сначала выбрать строки кода, а затем фрагмент кода, в который выбранные строки будут включены. Например, если выбрать нужные строки кода и затем активировать фрагмент кода for, то будет создан блок цикла for, внутри которого будут выбранные строки кода. Фрагменты кода ускоряют, упрощают написание программ и делают этот процесс более надежным.
Имхо можете попробовать templates из Resharper.

Framework


TransactionScope by KiwiBastard.Делает блок кода транзакционным. Данный класс не может быть унаследован.

Mutex by Diago

System.IO.Path by ageektrapped.Выполняет операции для экземпляров класса String, содержащих сведения пути к файлу или каталогу. Эти операции выполняются межплатформенным способом.

WeakReference by Juan Manuel.Представляет слабую ссылку, которая указывает на объект, но позволяет удалять его сборщику мусора.

Methods and Properties


String.IsNullOrEmpty() method by KiwiBastard.Указывает, является ли заданный объект String значением null (Nothing в Visual Basic) или строкой Empty.

List.ForEach() method by KiwiBastard
using System;
using System.Collections.Generic;


class Program
{
static void Main()
{
List<String> names = new List<String>();
names.Add(«Bruce»);
names.Add(«Alfred»);
names.Add(«Tim»);
names.Add(«Richard»);

// Display the contents of the List out using the «Print» delegate.
names.ForEach(Print);

// The following demonstrates the Anonymous Delegate feature of C#
// to display the contents of the List to the console.
names.ForEach(delegate(String name)
{
Console.WriteLine(name);
});
}

private static void Print(string s)
{
Console.WriteLine(s);
}
}
/* This code will produce output similar to the following:
* Bruce
* Alfred
* Tim
* Richard
* Bruce
* Alfred
* Tim
* Richard
*/

BeginInvoke(), EndInvoke() methods by Will Dean

Nullable<T>.HasValue and Nullable<T>. Value properties by Rismo

GetValueOrDefault method by John Sheehan.Извлекает значение текущего объекта Nullable(T) или заданное значение по умолчанию.

Tips & Tricks


uppercase comparisons by John.Исходя из книги «CLR via C#» Microsoft соптимизировали код для проведения UPPERCASE сравнений.(а НЕ LOWERCASE, например)

LINQBridge by Duncan Smart

Parallel Extensions by Joel Coehoorn.В докладе рассказывается об основных составляющих Parallel FX Jun 2008 CTP и приводятся примеры применения Parallel FX

оригинал ©
P.S. Столько коптел над форматированием кода, но Хабр чего-то никак не хочет послушаться =( профорвардил в своём блоге, там все отображается почти верно.

Progg it

Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
Total votes 83: ↑62 and ↓21+41
Comments56

Articles