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

Как ограничить T значениями типов с помощью ограничения?

Я хочу ограничить возможные типы N, которые можно взять с помощью ограничения. Я хочу ограничить N как int, так и десятичным.

public static Chart PopulateInto<T, N>(List<T> yAxis, List<N> xAxis) where N : int, decimal
{
    // Do stuff here
}

Любая помощь ценится...

4b9b3361

Ответ 1

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

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

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

Таким образом, вы не можете сделать это, но у вас есть несколько альтернатив:

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

    Поскольку у вас есть только два таких типа, я бы порекомендовал это сделать.

Вот перегрузки, которые вы бы объявили:

public static Chart PopulateInto<T>(List<T> yAxis, List<int> xAxis)
{
    // Do stuff here
}

public static Chart PopulateInto<T>(List<T> yAxis, List<decimal> xAxis)
{
    // Do stuff here
}

Теперь, кроме того, если ваша обработка этих значений на самом деле не зависит от числового качества этих типов, вы просто хотите ограничить, какие типы вы можете обрабатывать, тогда вы всегда можете объявить свой оригинальный метод, в частном порядке, и вызвать его метод от ваших перегрузок. Это по-прежнему будет ограничивать ваш код только публичным разрешением int или decimal, но ваша реализация все равно будет универсальной. Не зная точно, что влечет за собой "Делать что-то здесь", невозможно сказать, является ли это жизнеспособным вариантом или нет, но в любом случае вот код:

public static Chart PopulateInto<T>(List<T> yAxis, List<int> xAxis)
{
    return PopulateInto<T, int>(yAxis, xAxis);
}

public static Chart PopulateInto<T>(List<T> yAxis, List<decimal> xAxis)
{
    return PopulateInto<T, decimal>(yAxis, xAxis);
}

private static Chart PopulateInto<T, N>(List<T> yAxis, List<N> xAxis) where N : struct
{
    // Do stuff here
}

Ответ 2

Невозможно ограничить общий параметр определенным типом значения.

Однако вы можете заставить его быть типом значения или struct, добавив where N : struct, но все.

Ответ 3

Невозможно сделать это с помощью ограничения. Другой подход, предполагающий, что PopulateInto может работать с общим N, состоит в том, чтобы сделать основной алгоритм общим и частным и предложить 2 общедоступных перегрузки, которые принимают int и decimal соответственно. Это создаст аналогичный эффект

public static Chart PopulateInto<T>(
  List<T> yAxis, 
  List<decimal> xAxis) {

  return PopulateIntoCore(yAxis, xAxis);
}

public static Chart PopulateInto<T>(
  List<T> yAxis, 
  List<int> xAxis) {

  return PopulateIntoCore(yAxis, xAxis);
}

private static Chart PopulateIntoCore<T, N>(
  List<T> yAxis, 
  List<N> xAxis) where N : struct {
  ...
}

Ответ 4

Как сказал Питер, вы не можете использовать для этого проверку времени компиляции. Однако во время выполнения вы можете сделать следующее:

if(!(typeof(N).equals(typeof(int32))) && !(typeof(N).equals(typeof(decimal))))
  // do something

Ответ 5

Вы можете получить шкаф где T: struct, IComparable, IFormattable, IConvertible. Все типы значений реализуют эти интерфейсы.