Что означает where T : somevalue
? Я только что видел какой-то код, в котором говорилось where T : Attribute
. Я думаю, что это как-то связано с дженериками, но я не уверен, что это значит или что он делает.
Кто-нибудь знает?
Что означает where T : somevalue
? Я только что видел какой-то код, в котором говорилось where T : Attribute
. Я думаю, что это как-то связано с дженериками, но я не уверен, что это значит или что он делает.
Кто-нибудь знает?
Это ограничение параметра типа, что означает, что тип 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. Это называется ограничением голого типа.
Кроме того, что сказали другие, у вас также есть следующее:
Это способ ограничения типа, используемого в качестве универсальных аргументов. Так:
where T : SomeType
Означает, что T должен быть производным от SomeType или реализовывать интерфейс SomeType.
где Предложение используется для ограничения аргументов, которые могут быть переданы при использовании дженериков. При создании универсального класса в ваших интересах указать тип аргумента в зависимости от того, как вы планируете использовать T в своем классе. Если это что-то помимо того, что может сделать System.Object, то, вероятно, лучше всего использовать ограничение, так как вы получите ошибку времени компиляции по сравнению со временем выполнения.
пример
Если вы создаете класс
class Person<T> where T : System.IComparable<T>
{
//can now use CompareTo
}
Вы не можете не передать этому классу ничего, что не реализует IComparable. Так что теперь безопасно использовать CompareTo для всего, что передается в класс Person.