Предлагаю мой вольный перевод вопроса с stackoverflow, который мне показался полезным и сидит в фаворитах. Что-то я взял с MSDN (в основном вырезки из русской редакции), что-то -с блогов.
Все мы, С# разработчики, знаем базовые комманды C#. Я имею ввиду объявления, условия, циклы, операторы и т.д.
Некоторые из нас знают даже про Generics, anonymous types, lambdas, linq,…
Но, каковы реально скрытные возможности и трюки C#, про которые даже фанаты и эксперты не всегда знают?
/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.
number flaggings by Nick Berardi
one-parameter lambdas by Keith
auto properties by Keith
namespace aliases by Keith
verbatim string literals with @ by Patrick
(символ @ помогает исключить спец символы)
Любое numeric значение можно привести к enum:
format string brackets by Portman
property accessor accessibility modifiers by xanadont
ternary operator (
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.
object initializers by lomaxx.Одна из новинок С#3.0… Позволяет делать такие подмены:
То есть определять свойства, не используя конструктор.
Extension Methods by marxidad.Метода расширения позволяют «добавлять» методы в существующие типы без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Методы расширения являются особым видом статического метода, но они вызываются, как если бы они были методами экземпляра в расширенном типе. Для клиентского кода, написанного на языках C# и Visual Basic, нет видимого различия между вызовом метода расширения и вызовом методов, фактически определенных в типе.
Директивы препроцессора C# by John Asbeck
Перегрузки операторов by SefBkn.
boolean operators taken to next level by Rob Gough
snippets by DannySmurf.Среда разработки Visual Studio включает функцию, называемую «фрагменты кода». Фрагменты кода — это готовые фрагменты кода, которые можно быстро вставлять в свой код. Например, фрагмент кода for создает пустой цикл for. Некоторые фрагменты кода являются окружающими, т.е. позволяют сначала выбрать строки кода, а затем фрагмент кода, в который выбранные строки будут включены. Например, если выбрать нужные строки кода и затем активировать фрагмент кода for, то будет создан блок цикла for, внутри которого будут выбранные строки кода. Фрагменты кода ускоряют, упрощают написание программ и делают этот процесс более надежным.
Имхо можете попробовать templates из .
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. Столько коптел над форматированием кода, но Хабр чего-то никак не хочет послушаться =( профорвардил в своём блоге, там все отображается почти верно.
Все мы, С# разработчики, знаем базовые комманды 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 Stoneas
/ is
by Ed Swangrenas
/ is
(improved) by Rocketpantsdefault
by deathofratsglobal::
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 AndrewBurnsSyntax
??
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 AntonyLanguage 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 Himangoobject 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 из .
Framework
TransactionScope
by KiwiBastard.Делает блок кода транзакционным. Данный класс не может быть унаследован.Mutex
by DiagoSystem.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 KiwiBastardusing 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 DeanNullable<T>.HasValue
and Nullable<T>. Value
properties by RismoGetValueOrDefault
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. Столько коптел над форматированием кода, но Хабр чего-то никак не хочет послушаться =( профорвардил в своём блоге, там все отображается почти верно.