Могут ли дженерики C # иметь определенный базовый тип? - PullRequest
39 голосов
/ 23 октября 2008

Возможно ли, чтобы тип универсального интерфейса основывался на определенном родительском классе?

Например:

public interface IGenericFace<T : BaseClass>
{
}

Очевидно, что приведенный выше код не работает, но если это сработало, то я пытаюсь сказать компилятору, что T должен быть подклассом BaseClass. Можно ли это сделать, есть ли планы на это и т. Д.? 1008

Я думаю, что это было бы полезно с точки зрения конкретного проекта, чтобы убедиться, что универсальный интерфейс / класс не используется с непреднамеренными типами во время компиляции. Или также для сортировки самодокумента: покажите, какой тип предназначен.

Ответы [ 4 ]

86 голосов
/ 23 октября 2008
public interface IGenericFace<T> where T : SomeBaseClass
63 голосов
/ 23 октября 2008

То, на что вы ссылаетесь, называется «Общие ограничения». Существует множество ограничений, которые могут быть наложены на универсальный тип.

Вот несколько основных примеров:

  • where T: struct - Аргумент типа должен быть типом значения. Можно указать любой тип значения, кроме Nullable. См. Использование типов Nullable (Руководство по программированию в C #) для получения дополнительной информации.

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

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

  • where T : <base class name> - Аргумент типа должен быть или наследоваться от указанного базового класса.

  • where T : <interface name> - Аргумент типа должен быть или реализовывать указанный интерфейс. Можно указать несколько ограничений интерфейса. Ограничивающий интерфейс также может быть универсальным.

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

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

C #

public class TestClass<T> where T : MyBaseClass, INotifyPropertyChanged, new() { }
public interface IGenericFace<T> where T : SomeBaseClass

VB

Public Class TestClass(Of T As {MyBaseClass, INotifyPropertyChanged, New})
Public Interface IGenericInterface(Of T As SomeBaseClass)
5 голосов
/ 23 октября 2008

да.

public interface IGenericFace<T>
    where T : BaseClass
{
}
0 голосов
/ 23 октября 2008

Больше информации об общих интерфейсах: http://msdn.microsoft.com/en-us/library/kwtft8ak(VS.80).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...