Использование ключевого слова var в C#

после обсуждения с коллегами относительно использования ключевого слова " var " в C# 3 я задался вопросом, какие мнения людей были о соответствующем использовании вывода типа через var?

например, я довольно лениво использовал var в сомнительных обстоятельствах, например: -

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

более законным использованием var являются следующие: -

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

интересно, что LINQ кажется немного серой областью, например: -

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

ясно, какие результаты будут в это будет тип, который реализует IEnumerable, однако это не совсем очевидно, так же, как VAR, объявляющий новый объект.

это еще хуже, когда дело доходит до LINQ объектов, например: -

var results = from item in someList
              where item != 3
              select item;

Это не лучше, чем equivilent foreach(элемент var в someList) { // ... } equivilent.

существует реальная озабоченность по поводу безопасности типа вот, например, если мы должны были разместить результаты этого запроса в перегруженный метод, который принято IEnumerable и IEnumerable вызывающий может непреднамеренно передать неправильный тип.

var тут поддерживать сильную типизацию, но вопрос в том, действительно ли опасно для типа не быть сразу очевидным при определении, что-то, что увеличивается, когда перегрузки означают, что ошибки компилятора не могут быть выданы, когда вы непреднамеренно передаете неправильный тип методу.

30 ответов


Я все еще думаю var может сделать код более читаемым в некоторых случаях. Если у меня есть класс Customer со свойством Orders, и я хочу назначить это переменной, я просто сделаю это:

var orders = cust.Orders;

мне все равно, если клиент.Заказов IEnumerable<Order>, ObservableCollection<Order> или BindingList<Order> - все, что я хочу, это сохранить этот список в памяти, чтобы повторить его или получить его счет или что-то позже.

сравните приведенное выше объявление с:

ObservableCollection<Order> orders = cust.Orders;

для меня имя типа просто шум. И если я вернусь и решу изменить тип клиента.Заказы вниз по трассе (скажем, от ObservableCollection<Order> до IList<Order>) тогда мне тоже нужно изменить эту декларацию - то, что мне не пришлось бы делать, если бы я использовал var в первую очередь.


я использую var широко. Была критика, что это уменьшает читаемость кода, но нет аргументов в поддержку этого утверждения.

по общему признанию, это может означать, что неясно, с каким типом мы имеем дело. Ну и что? Это на самом деле точка разъединенного дизайна. При работе с интерфейсами, вы решительно не интересует тип переменной. var принимает это гораздо дальше, правда, но я думаю, что аргумент остается то же самое с точки зрения удобочитаемости: программиста должен интересовать не тип переменной, а то, что переменная тут. Вот почему Microsoft также называет вывод типа "утиный ввод"."

Итак, что делает переменная, когда я объявляю ее с помощью var? Легко, он делает все, что говорит мне IntelliSense. Любые рассуждения о C#, которые игнорируют IDE, не соответствуют реальности. На практике каждый код C# программируется в среде IDE, которая поддерживает технологию IntelliSense.

если я использую var объявленная переменная и запутаться, для чего существует переменная, есть что-то фундаментально неправильное с моим кодом. var не является причиной, это только делает симптомы видимыми. Не винить.

теперь команда C# выпустила Руководство по кодированию, в котором говорится, что var должны только используется для захвата результата оператора LINQ, который создает анонимный тип (потому что здесь мы у вас нет реальной альтернативы var). Ну и черт с ним. До тех пор, пока команда c# не даст мне разумный аргумент для этого руководства, я буду игнорировать его, потому что, по моему профессиональному и личному мнению, это чистая чушь. (Извините, у меня нет ссылки на данное руководство.)

на самом деле, есть некоторые (поверхностно) хороший объяснениями о том, почему вы не должны использовать var но я по-прежнему считаю, что они во многом ошибаются. Возьмем пример "searchabililty": автор утверждает, что var затрудняет поиск мест, где это. Право. Как и интерфейсы. На самом деле, зачем мне знать, где используется класс? Мне может быть более интересно, где он создается, и это все равно будет доступно для поиска, потому что где-то должен быть вызван его конструктор (даже если это делается косвенно, имя типа должно быть где-то упомянуто).


Var, на мой взгляд, в C# является хорошоtm. Любая типизированная таким образом переменная по-прежнему строго типизирована, но она получает свой тип из правой части назначения, где она определена. Поскольку информация о типе доступна с правой стороны, в большинстве случаев нет необходимости и слишком многословно вводить ее с левой стороны. Я думаю, что это значительно увеличивает читаемость без снижения безопасности типа.

из моего перспектива использование хороших соглашений об именах для переменных и методов более важно с точки зрения читаемости, чем явная информация о типе. Если мне нужна информация о типе, я всегда могу навести курсор на переменную (в VS) и получить ее. Как правило, однако, явная информация о типе не должна быть необходима читателю. Для разработчика в VS вы все равно получаете Intellisense, независимо от того, как объявлена переменная. Сказав Все это, все еще могут быть случаи, когда это имеет смысл чтобы явно объявить тип -- возможно, у вас есть метод, который возвращает List<T>, а вы хотите рассматривать его как IEnumerable<T> в свой способ. Чтобы убедиться, что вы используете интерфейс, объявление переменной типа интерфейса может сделать это явным. Или, возможно, вы хотите объявить переменную без начального значения - потому что она немедленно получает значение, основанное на некотором условии. В таком случае вам нужен тип. Если информация о типе полезна или необходима, используйте ее. Я чувствую, хотя, как правило, это не обязательно, и код легче читать без него в большинстве случаев.


ни то, ни другое не совсем верно;var может иметь как положительные, так и отрицательные последствия для читаемости. По-моему,var следует использовать, если выполняется одно из следующих условий:

  1. тип анонимный (ну, у вас нет выбора здесь, так как это должны быть var в этом случае)
  2. тип очевиден на основе назначенного выражения (т. е. var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

var не влияет на производительность, так как он синтаксический сахар; компилятор выводит тип и определяет его, как только он скомпилирован в IL; нет ничего на самом деле динамический об этом.


от Эрика Липперта, старшего инженера по разработке программного обеспечения в команде c#:

почему var ключевое слово ввел?

есть две причины, одна из которых существует сегодня, тот, который появится в 3.0.

первая причина в том, что этот код невероятно уродливый из-за всех избыточность:

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

и это простой пример – у меня есть написано хуже. В любое время вы вынуждены вводить точно то же самое дважды., это избыточность, которую мы можем удалять. Гораздо приятнее писать

var mylists = new Dictionary<string,List<int>>();

и пусть компилятор выяснить, что тип основан на назначении.

во-вторых, C# 3.0 представляет анонимный типы. Поскольку анонимные типы определения не имеют имен, ты нужно для уметь определить тип переменная от инициализации выражение, если его тип анонимный.

выделено мной. Вся статья,в C# 3.0 по-прежнему статически типизированный, честно! и в последующем серия довольно хорошо.

Это var для. Другие применения, вероятно, не будут работать так хорошо. Любое сравнение с JScript, VBScript или динамическим вводом-это полная койка. Еще раз обратите внимание,var is требуются для того, чтобы некоторые другие функции работали .Сеть.


Я думаю, что использование var должно сочетаться с мудро выбранными именами переменных.

у меня нет проблем с использованием var в инструкции foreach, если это не так:

foreach (var c in list) { ... }

если бы это было больше похоже на это:

foreach (var customer in list) { ... }

... тогда кто-то, читающий код, с большей вероятностью поймет, что такое "список". Если у вас есть контроль над именем самой переменной списка, это еще лучше.

то же самое можно применить к другим ситуациям. Это довольно бесполезно:

var x = SaveFoo(foo);

... но это имеет смысл:

var saveSucceeded = SaveFoo(foo);

каждому свое, Я думаю. Я обнаружил, что делаю это, что просто безумно:

var f = (float)3;

мне нужна какая-то 12-ступенчатая программа var. Меня зовут Мэтт, и я (ab)использую var.


мы приняли этос "код для людей, а не машин", основанный на предположении, что вы тратите в несколько раз больше времени в режиме обслуживания, чем на новую разработку.

для меня это исключает аргумент, что компилятор "знает", какой тип переменной-конечно, вы не можете написать недопустимый код в первый раз, потому что компилятор останавливает компиляцию вашего кода, но когда следующий разработчик читает код через 6 месяцев, они должны быть в состоянии вывести, что переменная делает правильно или неправильно и быстро определить причину проблемы.

таким образом,

var something = SomeMethod();

запрещено нашими стандартами кодирования, но в нашей команде поощряется следующее, потому что это повышает читаемость:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

это неплохо, это скорее стилистическая вещь, которая имеет тенденцию быть субъективной. Он может добавлять несоответствия, когда вы используете var, а когда нет.

еще один случай беспокойства, в следующем вызове вы не можете сказать, просто глядя на код типа, возвращаемого CallMe:

var variable = CallMe();

Это моя главная жалоба на var.

Я использую var, когда объявляю анонимных делегатов в методах, как-то var выглядит чище, чем если бы я использовал Func. Считать это код:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

редактировать: обновлен последний образец кода на основе ввода Джулиана


Var не похож на вариант вообще. Переменная по-прежнему строго типизирована, просто вы не нажимаете клавиши, чтобы получить ее таким образом. Вы можете навести курсор на него в Visual Studio, чтобы увидеть тип. Если Вы читаете печатный код, возможно, вам придется немного подумать, чтобы понять, что это за тип. Но есть только одна строка, которая объявляет его, и много строк, которые его используют, поэтому дать вещи приличные имена-все еще лучший способ сделать ваш код легче следовать.

использует Ленивый технологии IntelliSense? Это меньше, чем печатать полное имя. Или есть вещи, которые меньше работают, но не заслуживают критики? Я думаю, что есть, и Вар-один из них.


наиболее вероятное время, вам понадобится это для анонимных типов (где это требуется на 100%); но это также позволяет избежать повторения для тривиальных случаев, и IMO делает линию более четкой. Мне не нужно видеть тип дважды для простой инициализации.

например:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(пожалуйста, не редактируйте hscroll в выше - это доказывает!!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

есть, однако, случаи, когда это вводит в заблуждение и может потенциально вызвать ошибки. Будьте осторожны с использованием var если исходная переменная и инициализируется типа не идентичны. Например:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

один конкретный случай, когда var сложно: автономные обзоры кода, особенно те, которые сделаны на бумаге.

вы не можете полагаться на наведении курсора мыши на это.


Я не понимаю, в чем дело..

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

у вас все еще есть полный intellisense на "что-то", и для любого двусмысленного случая у вас есть модульные тесты, верно? (правда? )

это не varchar, это не тусклый, и это, конечно, не динамический или слабый набор текста. Это останавливает maddnes так:

List<somethinglongtypename> v = new List<somethinglongtypename>();

и сведение этого общего mindclutter к:

var v = new List<somethinglongtypename>();

хорошо, не совсем так хорошо, как:

v = List<somethinglongtypename>();

но тогда это то, что Бу для.


Если кто-то использует var ключевое слово, потому что они не хотят "выяснить тип", это определенно неправильная причина. The var ключевое слово не создать переменную с динамическим типом, компилятор все равно должен знать тип. Поскольку переменная всегда имеет определенный тип, тип также должен быть очевиден в коде, если это возможно.

веские причины использовать var ключевое слово, например:

  • где это необходимо, т. е. объявить ссылку для анонимного типа.
  • где он делает код более читаемым, т. е. удаляет repetetive объявления.

запись типа данных часто облегчает выполнение кода. Он показывает, какие типы данных вы используете, так что вам не нужно выяснять тип данных, сначала выясняя, что делает код.


учитывая, насколько мощный Intellisense сейчас, я не уверен, что var сложнее читать, чем иметь переменные-члены в классе или локальные переменные в методе, которые определены вне видимой области экрана.

Если у вас есть строка кода, такие как

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is намного легче или труднее читать, чем:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Я думаю, что ключевая вещь с VAR заключается в том, чтобы использовать его только там, где это необходимо, т. е. при выполнении вещей в Linq, которые он облегчает (и, вероятно, в других случаях).

Если вы получил тип для чего - то в то время вы должны использовать его - не делать этого-это простая лень (в отличие от творческой лени, которая обычно поощряется-хорошие программисты часто работают очень трудно быть ленивыми и могут считаться источником вещи в первую очередь).

A общий запрет так же плох, как злоупотребление конструкцией в первую очередь, но должен быть разумный стандарт кодирования.

другое дело, чтобы помнить, что это не тип VB var в том, что он не может изменять типы-это is строго типизированная переменная его просто, что тип выводится (именно поэтому есть люди, которые будут утверждать, что его неразумно использовать, скажем, в foreach, но я бы не согласился по причинам как читаемости, так и ремонтопригодность.)

Я подозреваю, что этот будет работать и работать ( -:

Мерф


конечно, int легко, но когда тип переменной IEnumerable<MyStupidLongNamedGenericClass<int, string>>, var делает вещи намного проще.


похищенные из сообщение по этому вопросу в CodingHorror:


к сожалению, вы и все остальные очень сильно ошибся. Хотя я согласен с вами, что избыточность не является хорошей вещью, лучшим способом решить эту проблему было бы сделать что-то вроде следующего:

MyObject m = new ();

или если вы передаете параметры:

Person p = new ("FirstName", "фамилия");

где при создании нового объекта компилятор выводит тип с левой стороны, а не с правой. У этого есть другие преимущества перед "var", в том, что он может использоваться и в объявлениях полей (есть также некоторые другие области, которые могут быть полезны, но я не буду вдаваться в это здесь).

В конце концов, это просто не было предназначено, чтобы уменьшить избыточность. Не поймите меня неправильно, "var" очень важен в C# для анонимных типов / проекций, но использование здесь просто далеко (и я говорю это в течение долгого, долгого времени) , поскольку вы запутываете тип, который используется. Необходимость вводить его дважды слишком часто, но объявление его нулевым разом слишком мало.

Николас Палдино .NET / C# MVP 20 июня 2008 08: 00 AM


Я думаю, если ваша главная забота состоит в том, чтобы напечатать меньше-тогда нет никаких аргументов, которые заставят вас отказаться от его использования.

Если вы только собираетесь когда-нибудь быть человеком, который смотрит на ваш код, затем какая разница? В противном случае в таком случае:

var people = Managers.People

это нормально, но в таком случае, как этот:

var fc = Factory.Run();

Он закорачивает любые немедленные выводы типа, которые мой мозг может начать формировать из "английского" кода.

в противном случае просто используйте свое лучшее суждение и программную "вежливость" по отношению к другим, которым, возможно, придется работать над вашим проектом.


используя var вместо явного типа делает рефакторинги намного проще (поэтому я должен противоречить предыдущим плакатам, которые имели в виду, что это не имело значения, или это был чисто "синтаксический сахар").

вы можете изменить тип возврата ваших методов без изменения каждого файла, где этот метод вызывается. Представьте

...
List<MyClass> SomeMethod() { ... }
...

, который используется как

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

если вы хотите рефакторинг SomeMethod() вернуть IEnumerable<MySecondClass>, вам придется изменить переменную декларация (также внутри foreach) в каждом месте вы использовали метод.

если вы пишите

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

вместо этого вам не нужно его менять.


@aku: один пример-обзоры кода. Другим примером является рефакторинг сценариев.

в основном я не хочу идти на охоту за типом с моей мышью. Он может быть недоступен.


это дело вкуса. Вся эта суета вокруг тип переменной исчезает, когда вы привыкаете к динамически типизированным языкам. То есть, Если вы когда-нибудь полюблю их (я не уверен, что все могут, но я делаю).

С var Это здорово, что он выглядит как динамическая типизация, но на самом деле это static typing - компилятор обеспечивает правильное использование.

тип переменной не действительно, это важно (это было сказано ранее). Это должно быть относительно ясно из контекста (его взаимодействия с другими переменными и методами) и его имени - не ожидайте customerList содержит int...

Я все еще жду, что мой босс думает об этом вопросе - у меня есть одеяло "вперед", чтобы использовать любые новые конструкции в 3.5, но что мы будем делать с обслуживанием?


в вашем сравнении между IEnumerable<int> и IEnumerable<double> вам не нужно беспокоиться - если вы передаете неверный тип ваш код не будет компилироваться.

никакая забота о тип-безопасности, как var is не динамические. Это просто компилятор магии и любого типа небезопасные вызовы будут пойманы.

Var абсолютно необходимо для Linq:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

теперь посмотрим на anonEnumeration в intellisense, и он появится что-то вроде IEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

компилятор C# довольно умный-типы anon, сгенерированные отдельно, будут иметь тот же сгенерированный тип, если их свойства совпадают.

вне этого, пока у вас есть intellisense, имеет смысл использовать var везде, где контекст ясен.

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;

Я думаю, это зависит от вашей точки зрения. Я лично никогда не испытывал никаких трудностей с пониманием фрагмента кода из-за var "неправильное использование", и мои коллеги и я используем его довольно много. (Я согласен, что Intellisense-огромная помощь в этом отношении.) Я приветствую его как способ удалить повторяющийся cruft.

в конце концов, если заявления типа

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

если бы это было действительно невозможно, никто не использовал бы динамически типизированные языки.


Я использую var только тогда, когда ясно, какой тип используется.

например, я бы использовал var в этом случае, потому что вы сразу видите, что x будет иметь тип "MyClass":

var x = new MyClass();

Я бы не использовал var в таких случаях, потому что вам нужно перетащить мышь над кодом и посмотреть на подсказку, чтобы увидеть, какой тип myfunction возвращает:

var x = MyClass.MyFunction();

Особенно, Я никогда используйте var в случаях, когда правая сторона даже не является методом, но только значение:

var x = 5;

(потому что компилятор не может знать, хочу ли я байт, короткий, int или что-то еще)


ко мне, антипатия к var иллюстрирует, почему двуязычие в .NET важно. Для тех программистов C#, которые также сделали VB .NET, преимущества var интуитивно понятно. Стандартное объявление C#:

List<string> whatever = new List<string>();

эквивалентно, в VB .NET, набрав это:

Dim whatever As List(Of String) = New List(Of String)

никто не делает этого в VB .NET, хотя. Было бы глупо, потому что с первой версии .NET вы смогли это сделать этот...

Dim whatever As New List(Of String)

...который создает переменную и инициализирует ее в одной достаточно компактной строке. Ах, но что, если вы хотите IList<string>, а не List<string>? Ну, в VB .NET это означает, что вы должны сделать это:

Dim whatever As IList(Of String) = New List(Of String)

так же, как вы должны были бы сделать в C#, и, очевидно, не могли использовать var для:

IList<string> whatever = new List<string>();

если вы нужно тип, чтобы быть чем-то другим, это может быть. Но один из основных принципов хорошего программирования сокращение избыточности, и это именно то, что делает var.


используйте его для анонимных типов-вот для чего он там. Все остальное бесполезно. Как и многие люди, выросшие на C, я привык смотреть слева от объявления для типа. Я не смотрю на правую сторону, пока не придется. Используя var для любой старой декларации заставляет меня делать это все время, которое я лично нахожу неудобным.

те, кто говорит: "это не имеет значения, используйте то, что вам нравится", не видят всей картины. Все подберут другие код людей в тот или иной момент и должен иметь дело с любыми решениями, которые они приняли в то время, когда они его написали. Достаточно плохо иметь дело с радикально разными соглашениями об именах или-классическими стилями сцепления, не добавляя всего"var или дело не в смеси. В худшем случае один программист не использовал var а затем приходит сопровождающий, который любит его, и расширяет код, используя его. Так что теперь у тебя нечестивый беспорядок.

стандарты это хорошо именно потому, что они означают, что вы, скорее всего, сможете подобрать случайный код и сможете быстро его обработать. Чем больше вещей отличается, тем труднее становится. И переход к стилю "var everywhere" делает большой разницы.

Я не против динамического набора текста, и я не против implict ввода языков, которые предназначены для них. Мне очень нравится Python. Но C# был разработан как статически явно типизированный язык, и именно так он должен остаться. Нарушение правил для анонимных типов было достаточно плохо; позволить людям взять это еще дальше и сломать идиомы языка еще больше-это то, что мне не нравится. Теперь, когда джинн вышел из бутылки, он никогда не вернется. C# станет балканизированным в лагеря. Не хороший.


много раз во время тестирования у меня есть такой код:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

Теперь, иногда, я хочу посмотреть, что содержит сам Sometherthing, Sometherthing не тот же тип, который возвращает CallMethod (). Поскольку я использую var, я просто изменяю это:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

для этого:

var something = myObject.SomeProperty.SomeOtherThing;

без var мне пришлось бы продолжать изменять объявленный тип с левой стороны. Я знаю, что это незначительно, но это очень удобно.


для afficionados, которые думают var экономит время, для ввода требуется меньше нажатий клавиш:

StringBuilder sb = new StringBuilder();

чем

var sb = new StringBuilder();

считай их, если не веришь мне...

19 против 21

я объясню, если придется, но просто попробуйте... (в зависимости от текущего состояния вашего intellisense вам может потребоваться ввести еще пару для каждого из них)

и это верно для каждого типа вы можете думать!!

мое личное чувство, что var никогда не следует использовать, за исключением случаев, когда тип не известен, поскольку он уменьшает распознавание readabiltiy в коде. Мозгу требуется больше времени, чтобы распознать тип, чем полная строка. Старые таймеры, которые понимают машинный код и биты, точно знают, о чем я говорю. Мозг работает параллельно, и когда вы используете var, вы заставляете его сериализовать свой вход. Зачем кому-то заставлять свой мозг работать усерднее? Для этого и существуют компьютеры.


Я разделил var по всем местам, единственными сомнительными местами для меня являются внутренние короткие типы, например, я предпочитаю int i = 3; над var i = 3;


Это, безусловно, может сделать вещи проще, из кода я написал:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

Это было бы чрезвычайно многословно без var.

добавление: немного времени, проведенного с языком с реальные вывод типа (например, F#) покажет, насколько хороши компиляторы при правильном типе выражений. Это, конечно, означало, что я склонен использовать var столько, сколько я могу, и использование явного типа теперь указывает, что переменная не имеет инициализация типа выражения.


нет, за исключением того, что вам не нужно писать имя типа дважды. http://msdn.microsoft.com/en-us/library/bb383973.aspx