Tuesday, May 11, 2010

Использование неявно типизированных переменных в C#

Ещё в C# 3.0 появилась довольно интересная фича — неявная типизация переменных. При объявлении переменной мы можем не задавать явно её тип — его определит компилятор. В основном это будет полезно при использовании анонимных типов и LINQ-запросов, но абсолютно ничего не мешает нам использовать её и в обычном коде:
int i = 42; // явное задание типа
var j = 42; // неявное задание типа
В примере выше переменная j будет типа int точно так же, как и i. При желании можно легко в этом убедиться, заглянув в MSIL:
IL_0000:  nop
IL_0001:  ldc.i4.s   42
IL_0003:  stloc.0
IL_0004:  ldc.i4.s   42
IntelliSense в Visual Studio также без проблем разбирается с неявно типизированными переменными:
Оператор var
можно использовать как в циклах for, так и в объявлениях using. Но по-настоящему он пригодится, когда мы возпользуемся анонимными типами, например, в LINQ-запросе. В таком случае, наша переменная может быть объявлена только через идентификатор var, потому что внутреннее название сгенерированного анонимного типа будет известно только компилятору:
struct SomeStruct
{
    public int a;
    public int b;
    public int c;
}
static void Main(string[] args)
{
    int[] numbers = new[] { 0, 1, 2, 3, 4, 5 };
    // здесь использование var необязательно - мы можем использовать
    // вместо него явно заданный IEnumerable
    var numberQuery = from number in numbers
                      where number > 1 && number <= 4
                      select number;
    // так как numberQuery - объект неанонимного типа, в foreach можно
    // использовать явно типизированный итератор
    foreach (int i in numberQuery)
    {
        Console.WriteLine(i.ToString());
    }

    SomeStruct[] structures = new[] {
        new SomeStruct { a=1,b=2,c=3},
        new SomeStruct { a=3,b=4,c=5},
        new SomeStruct { a=7,b=8,c=9},
    };

    // результат этого запроса - коллекция экземпляров анонимного типа.
    // в данном случае использование var обязательно.
    var structQuery = from structure in structures
                      where structure.a <= 3
                      select new { NewA = structure.a, NewB = structure.b };
    // опять же, из-за анонимности типа в LINQ-запросе, мы не можем явно
    // указать тип итератора, поэтому обязательно использовать var.
    foreach (var j in structQuery)
    {
        Console.WriteLine(String.Format("NewA={0},NewB={1}", j.NewA, j.NewB));
    }
}

Итак, неявно типизированные переменные и идентификатор var  — отличное средство улучшения читабельности и лёгкости написания кода (сравните var someQuery и IEnumerable<somelongandnastytype> someQuery !) и незаменимое решение при использовании анонимных типов.

Implicitly Typed Local Variables (C# Programming Guide)
Anonymous Types (C# Programming Guide)

No comments:

Post a Comment