Прочитав это , я узнал, что можно разрешить методу принимать параметры нескольких типов, сделав его универсальным методом. В этом примере следующий код используется с ограничением типа, чтобы гарантировать, что «U» является IEnumerable<T>
.
public T DoSomething<U, T>(U arg) where U : IEnumerable<T>
{
return arg.First();
}
Я нашел еще код, который позволил добавить несколько ограничений типа, например:
public void test<T>(string a, T arg) where T: ParentClass, ChildClass
{
//do something
}
Однако этот код, похоже, arg
требует, чтобы они были как типа, так ParentClass
и ChildClass
. Я хочу сказать, что arg может быть типом ParentClass
или ChildClass
следующим образом:
public void test<T>(string a, T arg) where T: string OR Exception
{
//do something
}
Ваша помощь как всегда ценится!
c#
asp.net-mvc-3
types
Mansfield
источник
источник
where T : string
, так какstring
это закрытый класс. Единственная полезная вещь, которую вы могли бы сделать, это определить перегрузки дляstring
иT : Exception
, как объяснил @ Botz3000 в своем ответе ниже.arg
это те, которые определеныobject
- так почему бы просто не удалить обобщенные элементы из рисунка и создать типarg
object
? Что вы получаете?Ответы:
Это невозможно. Однако вы можете определить перегрузки для определенных типов:
Если они являются частью универсального класса, они будут предпочтительнее, чем универсальная версия метода.
источник
or
отношения делают вещи очень полезными. Вам придется поразмыслить, чтобы понять, что делать, и все такое. (YUCK!).Ответ Botz на 100% правильный, вот краткое объяснение:
Когда вы пишете метод (общий или нет) и объявляете типы параметров, которые принимает метод, вы определяете контракт:
Если вы попытаетесь дать ему более одного типа за раз (используя или) или попытаетесь заставить его возвращать значение, которое может быть более чем одного типа, контракт станет нечетким:
Проблема в том, что когда вы попадаете в метод, вы не представляете, дали ли они вам
IJumpRope
илиPiFactory
. Более того, когда вы продолжаете использовать этот метод (при условии, что вы научились его волшебным образом скомпилировать), вы не совсем уверены, есть ли у вас aFisher
илиAbstractConcreteMixer
. По сути, это делает все это более запутанным.Решение вашей проблемы - одна из двух возможностей:
Определите более одного метода, который определяет каждое возможное преобразование, поведение или что-либо еще. Это ответ Ботца. В мире программирования это называется перегрузкой метода.
Определите базовый класс или интерфейс, который знает, как делать все, что вам нужно для метода, и пусть один метод принимает только этот тип. Это может включать в себя упаковку
string
иException
в небольшой класс, чтобы определить, как вы планируете сопоставить их с реализацией, но тогда все будет очень ясно и легко читается. Я мог бы прийти через четыре года и прочесть твой код и легко понять, что происходит.То, что вы выберете, зависит от того, насколько сложным будет выбор 1 и 2 и насколько он должен быть расширяемым.
Поэтому для вашей конкретной ситуации я собираюсь представить, что вы просто извлекаете сообщение или что-то из исключения:
Теперь все, что вам нужно, это методы, которые преобразуют a
string
и aException
в IHasMessage. Очень просто.источник
Если ChildClass означает, что он является производным от ParentClass, вы можете просто написать следующее, чтобы принять как ParentClass, так и ChildClass;
С другой стороны, если вы хотите использовать два разных типа без отношения наследования между ними, вам следует рассмотреть типы, реализующие один и тот же интерфейс;
тогда вы можете написать свою общую функцию как;
источник
Несмотря на возраст этого вопроса, я все еще получаю случайные голоса за свое объяснение выше. Объяснение все еще прекрасно, как есть, но я собираюсь ответить во второй раз с типом, который послужил мне хорошим заменителем типов объединения (строго типизированный ответ на вопрос, который не поддерживается в C # как есть ).
Выше класс представляет собой тип , который может быть либо TP или TA. Вы можете использовать его как таковой (типы относятся к моему первоначальному ответу):
Важные заметки:
IsPrimary
сначала.IsNeither
IsPrimary
илиIsAlternate
.Primary
иAlternate
Either
где угодно, где ожидается. Если вы делаете пройтиEither
гдеTA
илиTP
как ожидается, ноEither
содержит неправильный тип значения , вы получите сообщение об ошибке выполнения.Я обычно использую это там, где я хочу, чтобы метод возвращал либо результат, либо ошибку. Это действительно очищает этот стиль кода. Я также очень редко ( редко ) использую это как замену перегрузок методов. Реально это очень плохая замена такой перегрузки.
источник