Подтвердить что ты не робот

Общий метод, где T - type1 или type2

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

Пример:

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

Могу ли я ограничить T значением int или long

4b9b3361

Ответ 1

Вы можете использовать общие ограничения, чтобы ограничить тип каждого общего аргумента. К сожалению, не существует общих ограничений, которые позволяли бы во время компиляции принудительно вводить ли T type1 or type2. Во время компиляции нет возможности принудительно использовать ваш общий аргумент любого примитивного типа (int, long, double,...).

Ответ 2

Нет.

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

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

Ответ 3

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

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

}

...

public interface IMyType
{
}

public class Type1 : IMyType
{
}

public class Type2 : IMyType
{
}

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

public void DoIt(long someParameter)
{

}

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

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

}

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

Ответ 4

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

public void Foo(int number)
{
} 

public void Foo(long number)
{
}

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

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

Ответ 5

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

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

Ответ 6

Я знаю, что это старый вопрос, и это не отвечает на него, но вы можете сделать это с помощью одного метода, а не создавать множественные значения или использовать общие ограничения... особенно полезно, если у вас есть 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
}

Ответ 7

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

Смешивание 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();
}

Мне кажется, это может быть полезно.:)