有人能告诉我是否有一种方法可以用泛型将泛型类型参数T限制为:

Int16 Int32 Int64 UInt16 UInt32 UInt64

我知道哪里关键字,但不能找到只有这些类型的接口,

喜欢的东西:

static bool IntegerFunction<T>(T value) where T : INumeric 

当前回答

不幸的是,. net并没有提供一种本地的方法。

为了解决这个问题,我创建了OSS库generatics,它为以下内置数字类型及其可空等价提供了大多数标准数字操作,并能够添加对其他数字类型的支持。

sbyte、byte、short、ushort、int、uint、long、ulong、float、double、decimal、BigInteger

其性能相当于特定于数值类型的解决方案,允许您创建高效的通用数值算法。

下面是一个代码使用示例。

public static T Sum(T[] items)
{
    T sum = Number.Zero<T>();
    foreach (T item in items)
    {
        sum = Number.Add(sum, item);
    }
    return sum;
}
public static T SumAlt(T[] items)
{
    // implicit conversion to Number<T>
    Number<T> sum = Number.Zero<T>();
    foreach (T item in items)
    {
        // operator support
        sum += item;
    }
    // implicit conversion to T
    return sum;
}

其他回答

我创建了一个小库功能来解决这些问题:

而不是:

public T DifficultCalculation<T>(T a, T b)
{
    T result = a * b + a; // <== WILL NOT COMPILE!
    return result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Should result in 8.

你可以这样写:

public T DifficultCalculation<T>(Number<T> a, Number<T> b)
{
    Number<T> result = a * b + a;
    return (T)result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Results in 8.

你可以在这里找到源代码:https://codereview.stackexchange.com/questions/26022/improvement-requested-for-generic-calculator-and-generic-number

目前还没有“好的”解决方案。但是,您可以显著地缩小类型参数,以排除许多与您假设的“INumeric”约束不匹配的情况,如上面haacks所示。

static bool IntegerFunction<T>(T值)where T: IComparable, iformatable, IConvertible, IComparable<T>, IEquatable<T>, struct {…

这个练习的意义是什么?

正如人们已经指出的,你可以让一个非泛型函数取最大的项,编译器会自动为你转换较小的整型。

static bool IntegerFunction(Int64 value) { }

如果您的函数处于性能关键的路径上(在我看来,这是不太可能的),您可以为所有需要的函数提供重载。

static bool IntegerFunction(Int64 value) { }
...
static bool IntegerFunction(Int16 value) { }

不幸的是,. net并没有提供一种本地的方法。

为了解决这个问题,我创建了OSS库generatics,它为以下内置数字类型及其可空等价提供了大多数标准数字操作,并能够添加对其他数字类型的支持。

sbyte、byte、short、ushort、int、uint、long、ulong、float、double、decimal、BigInteger

其性能相当于特定于数值类型的解决方案,允许您创建高效的通用数值算法。

下面是一个代码使用示例。

public static T Sum(T[] items)
{
    T sum = Number.Zero<T>();
    foreach (T item in items)
    {
        sum = Number.Add(sum, item);
    }
    return sum;
}
public static T SumAlt(T[] items)
{
    // implicit conversion to Number<T>
    Number<T> sum = Number.Zero<T>();
    foreach (T item in items)
    {
        // operator support
        sum += item;
    }
    // implicit conversion to T
    return sum;
}

不幸的是,在这种情况下,只能在where子句中指定struct。不能具体指定Int16、Int32等,这看起来确实很奇怪,但我相信,在决定不允许在where子句中使用值类型的基础上,有一些深层的实现原因。

我想唯一的解决方案是执行运行时检查,这不幸地阻止了在编译时拾取问题。大概是这样的:-

static bool IntegerFunction<T>(T value) where T : struct {
  if (typeof(T) != typeof(Int16)  &&
      typeof(T) != typeof(Int32)  &&
      typeof(T) != typeof(Int64)  &&
      typeof(T) != typeof(UInt16) &&
      typeof(T) != typeof(UInt32) &&
      typeof(T) != typeof(UInt64)) {
    throw new ArgumentException(
      string.Format("Type '{0}' is not valid.", typeof(T).ToString()));
  }

  // Rest of code...
}

我知道这有点难看,但至少提供了所需的约束条件。

我还将研究此实现可能的性能影响,也许有更快的方法。