C # Generics, ограничение для конкретных структур - PullRequest
5 голосов
/ 29 ноября 2009

Можно ли ограничить обобщенный метод приемом только определенных типов структур?

Это нормально, я верю:

string Add<T>(object value, T expiration) where T : struct; 

но это не так:

string Add<T>(object value, T expiration) where T : Struct1, Struct2; 

Примечание. Структуры, которыми я хочу ограничить это DateTime или TimeSpan, и поэтому я не могу их контролировать.

Спасибо

Ответы [ 4 ]

7 голосов
/ 29 ноября 2009

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

Помните также, что C # generics не являются шаблонами C ++. Когда вы вызываете метод для параметра типа, скажем, что вызов метода будет точно таким же вызовом метода для каждой конструкции параметра типа. Это универсальный . Это не шаблон, в котором компилятор компилирует код два, три, тысячу раз, по одному для каждого аргумента типа, и заново вырабатывает для каждого, что является вызовом метода.

Так что, даже если вы могли бы ограничить ваш аргумент типа двумя типами, что хорошего это вам даст? Все, что вы могли вызвать для них, - это методы, которые у них были общие через базовый класс Object. В этом случае у вас есть универсальный метод, который работает со всеми объектами, так зачем ограничивать его двумя типами?

7 голосов
/ 29 ноября 2009

Нет, поскольку структура запечатана (вы не можете создать подкласс ValueType).

Вместо этого рассмотрите возможность реализации в ваших структурах интерфейса, а затем используйте это как ограничение, например:

string Add<T>(object value, T expiration) where T : struct, IMyInterface

5 голосов
/ 29 ноября 2009

Я ожидаю, что перегрузка - ваш лучший вариант здесь:

string Add(object value, MyStruct1 expiration) {...}
string Add(object value, MyStruct2 expiration) {...}

Это даже более уместно, поскольку вы не можете создать подкласс структуры, поэтому only viable T в вашем примере будет MyStruct1 и MyStruct2 - может а также есть конкретные методы, то.

Ограничение дженериков несколькими цитируемыми типами; не совсем - и даже если бы они были, название «Добавить» предполагает, что вы хотите использовать поддержку оператора, которой также нет в C # (3.0).

Однако в C # 4.0 здесь может быть опция dynamic - это действует как оптимизированная форма утки; вы не получите поддержку компилятора (проверка и т. д.), но это должно работать. Вы бы применили dynamic внутри метод:

string Add<T>(object value, T expiration) where T : struct {
    dynamic valueDyn = value;
    valueDyn += expiration; // or similar
    // more code
}

Другой вариант (в .NET 3.5) - использовать поддержку Operator в MiscUtil , используя Operator.Add или Operator.AddAlternative.

0 голосов
/ 29 ноября 2009

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

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