Общий метод, где T - это type1 или type2 - PullRequest
25 голосов
/ 18 декабря 2011

Есть ли способ объявить универсальную функцию, что универсальный тип имеет тип1 или тип2?

пример:

public void Foo<T>(T number)
{
}

Могу ли я ограничить T быть int или long

Ответы [ 7 ]

16 голосов
/ 28 сентября 2016

Для объектов ReferenceType вы можете сделать

public void DoIt<T>(T someParameter) where T : IMyType
{

}

...

public interface IMyType
{
}

public class Type1 : IMyType
{
}

public class Type2 : IMyType
{
}

Для вашего случая использование long в качестве параметра будет ограничивать использование long и int в любом случае.

public void DoIt(long someParameter)
{

}

для ограничения любыми типами значений (такими как: int, double, short, decimal), которые вы можете использовать:

public void DoIt<T>(T someParameter) where T : struct
{

}

для получения дополнительной информации вы можете проверить официальную документацию здесь

15 голосов
/ 18 декабря 2011

Хотя вы можете использовать универсальное ограничение , чтобы ограничить тип каждого универсального аргумента T, к сожалению, нет ни одного, который позволил бы вам принудительно установить во время компиляции, равен ли T type1 or type2.

Также нет способа обеспечить во время компиляции, что ваш универсальный аргумент может быть только любого примитивного типа (int, long, double, ...).

8 голосов
/ 18 декабря 2011

номер

Это не имеет смысла; T не будет иметь никакого используемого типа времени компиляции в методе.

Вместо этого вы должны сделать два перегруженных метода.

5 голосов
/ 18 декабря 2011

Вместо этого используйте перегруженные методы:

public void Foo(int number)
{
} 

public void Foo(long number)
{
}

Вы не можете выполнять арифметические операции с универсальными типами.Обратите внимание, что вы можете передать значение int параметру long.Он будет автоматически преобразован в long.Поэтому достаточно иметь только один метод с параметром long.

Старые языки программирования работали по принципу «может быть только один».C # позволяет вам иметь несколько методов с одинаковым именем в одном классе, интерфейсе или структуре.Эти методы должны иметь другую подпись.Это означает, что они должны иметь разное количество параметров или параметры с разными типами (или оба).Это называется перегрузкой метода.

1 голос
/ 16 декабря 2015

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

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

public void MyMethod<T>()
{
    if (!typeof(T).Equals(typeof(int)) &&
        !typeof(T).Equals(typeof(long)))
            throw new Exception("T must be int or long");

    //your logic here
}
0 голосов
/ 23 февраля 2016

У меня также была эта проблема, и я думаю, что нашел лучшее решение (при условии, что перегруженной версии вашего метода недостаточно):

Смешивание Type1 и Type2 без каких-либо параллелей не имеет никакого смысла, как уже было написано. Таким образом, должен быть любой метод или свойство, к которому осуществляется доступ для обоих типов объектов. Чтобы убедиться, что эти методы или свойства доступны для вашего объекта, сгруппируйте Type1 и Type2, создав интерфейс MyInterface и реализовав его по Type1 и Type2:

interface MyInterface {
  void MyCommonMethod();
  bool MyCommonProperty { get; }
}

class Type1 : MyInterface {
  void MyCommonMethod() {
    // TODO: Implement it for Type1
  }

  bool MyCommonProperty {
  get {
    // TODO: Implement it for Type1
  }
  }
}

class Type2 : MyInterface {
  void MyCommonMethod() {
    // TODO: Implement it for Type2
  }

  bool MyCommonProperty {
  get {
    // TODO: Implement it for Type2
  }
  }
}

Теперь, чтобы переписать ваш метод Foo, чтобы принять Type1 и Type2, ограничение T должно быть MyInterface объектом:

public void Foo<T>(T number) where T : MyInterface
{
  throw new NotImplementedException();
}

Я думаю, это может быть полезно. :)

0 голосов
/ 18 декабря 2011

Я не думаю, что это в настоящее время возможно.

Этот вопрос о создании математической библиотеки охватывает то же основание и включает некоторые обходные пути.

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