Что означает where T : somevalue?

Что означает where T : somevalue? Я только что видел какой-то код, в котором говорилось where T : Attribute. Я думаю, что это как-то связано с дженериками, но я не уверен, что это значит или что он делает.

Кто-нибудь знает?


person mikpy    schedule 07.03.2009    source источник


Ответы (4)


Это ограничение параметра типа, что означает, что тип T, присвоенный универсальному классу или методу, должен наследоваться от класса Attribute

Например:

public class Foo<T> : 
   where T : Attribute
{
    public string GetTypeId(T attr) { return attr.TypeId.ToString(); }
 // ..
}

Foo<DescriptionAttribute> bar; // OK, DescriptionAttribute inherits Attribute
Foo<int> baz; // Compiler error, int does not inherit Attribute

Это полезно, потому что позволяет универсальному классу работать с объектами типа T, зная, что все, что является T, также должно быть Attribute.

В приведенном выше примере для GetTypeId нормально запрашивать TypeId из attr, потому что TypeId является свойством Attribute, а поскольку attr является T, он должен быть типом, унаследованным от Attribute.

Ограничения также можно использовать в универсальных методах с тем же эффектом:

public static void GetTypeId<T>(T attr) where T : Attribute
{
   return attr.TypeId.ToString();
}

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

where T: struct

Аргумент типа должен быть типом значения. Можно указать любой тип значения, кроме Nullable.

where T : class

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

where T : new()

Аргумент типа должен иметь общедоступный конструктор без параметров. При использовании вместе с другими ограничениями ограничение new() должно указываться последним.

where T : <base class name>

Аргумент типа должен быть или производным от указанного базового класса.

where T : <interface name>

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

where T : U

Аргумент типа, предоставленный для T, должен быть или производным от аргумента, предоставленного для U. Это называется ограничением голого типа.

person Daniel LeCheminant    schedule 07.03.2009
comment
+1 Это довольно всеобъемлюще. Хотел бы я добавить ответ в избранное. - person dance2die; 13.03.2009

Кроме того, что сказали другие, у вас также есть следующее:

  • new() - T должен иметь конструктор по умолчанию
  • class - T должен быть ссылочным типом
  • struct - T должен быть типом значения
person leppie    schedule 07.03.2009

Это способ ограничения типа, используемого в качестве универсальных аргументов. Так:

where T : SomeType

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

person Sean    schedule 07.03.2009

где Предложение используется для ограничения аргументов, которые могут быть переданы при использовании дженериков. При создании универсального класса в ваших интересах указать тип аргумента в зависимости от того, как вы планируете использовать T в своем классе. Если это что-то помимо того, что может сделать System.Object, то, вероятно, лучше всего использовать ограничение, так как вы получите ошибку времени компиляции по сравнению со временем выполнения.

пример

Если вы создаете класс

class Person<T> where T : System.IComparable<T>
{
   //can now use CompareTo
}

Вы не можете не передать этому классу ничего, что не реализует IComparable. Так что теперь безопасно использовать CompareTo для всего, что передается в класс Person.

person cgreeno    schedule 07.03.2009