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

Int16 Int32 Int64 UInt16 UInt32 UInt64

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

喜欢的东西:

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

当前回答

如果你只想使用一个数字类型,你可以考虑用using在c++中创建类似于别名的东西。

因此,我们不再使用非常通用的

T ComputeSomething<T>(T value1, T value2) where T : INumeric { ... }

你可以

using MyNumType = System.Double;
T ComputeSomething<MyNumType>(MyNumType value1, MyNumType value2) { ... }

如果需要,这可能允许您轻松地将double类型转换为int类型或其他类型,但您不能在同一个程序中使用带有double类型和int类型的computessomething。

但为什么不把所有double都换成int呢?因为你的方法可能想要使用double类型不管输入是double型还是int型。别名允许您确切地知道哪个变量使用了动态类型。

其他回答

这是没有限制的。对于任何想要使用泛型进行数值计算的人来说,这都是一个真正的问题。

更进一步说,我们需要

static bool GenericFunction<T>(T value) 
    where T : operators( +, -, /, * )

甚至

static bool GenericFunction<T>(T value) 
    where T : Add, Subtract

不幸的是,你只有接口,基类和关键字struct(必须是值类型),class(必须是引用类型)和new()(必须有默认构造函数)

你可以把数字包装在其他东西(类似于INullable<T>),就像这里的codeproject。


您可以在运行时应用该限制(通过对操作符进行反射或检查类型),但这首先就失去了使用泛型的优势。

当我试图重载泛型类型的操作符时,这个限制影响了我;由于没有“innumeric”约束,以及stackoverflow上的优秀人员乐于提供的一系列其他原因,操作不能在泛型类型上定义。

我想要的是

public struct Foo<T>
{
    public T Value{ get; private set; }

    public static Foo<T> operator +(Foo<T> LHS, Foo<T> RHS)
    {
        return new Foo<T> { Value = LHS.Value + RHS.Value; };
    }
}

我已经使用。net4动态运行时类型解决了这个问题。

public struct Foo<T>
{
    public T Value { get; private set; }

    public static Foo<T> operator +(Foo<T> LHS, Foo<T> RHS)
    {
        return new Foo<T> { Value = LHS.Value + (dynamic)RHS.Value };
    }
}

关于使用动态的两件事是

的性能。所有值类型都被装箱。 运行时错误。你“打败”了编译器,但失去了类型安全。如果泛型类型没有定义操作符,则会在执行期间抛出异常。

这个约束存在于。net 7中。

查看这篇。net博客文章和实际文档。

从。net 7开始,你可以使用接口如INumber和IFloatingPoint来创建程序,例如:

using System.Numerics;

Console.WriteLine(Sum(1, 2, 3, 4, 5));
Console.WriteLine(Sum(10.541, 2.645));
Console.WriteLine(Sum(1.55f, 5, 9.41f, 7));

static T Sum<T>(params T[] numbers) where T : INumber<T>
{
    T result = T.Zero;

    foreach (T item in numbers)
    {
        result += item;
    }

    return result;
}

innumber在系统中。数字名称空间。

还有诸如IAdditionOperators和IComparisonOperators这样的接口,因此您可以通用地使用特定的操作符。

这个问题有点像常见问题,所以我在维基上发布了这个(因为我之前发布过类似的问题,但这是一个较老的问题);无论如何……

你用的是什么版本的。net ?如果你使用的是。net 3.5,那么我在MiscUtil中有一个通用操作符实现(免费等)。

它有T Add<T>(T x, T y)等方法,以及不同类型上的其他算术变体(如DateTime + TimeSpan)。

此外,这适用于所有内置、提升和定制操作符,并缓存委托以获得性能。

这里有一些关于为什么这很棘手的额外背景。

你可能还想知道动态(4.0)也间接地解决了这个问题。

dynamic x = ..., y = ...
dynamic result = x + y; // does what you expect

也许你能做的就是

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

不确定你是否能做到以下几点

static bool IntegerFunction<T>(T value) where T: struct, IComparable
, IFormattable, IConvertible, IComparable<T>, IEquatable<T>

对于如此特定的内容,为什么不为每种类型设置重载呢?列表很短,而且可能占用更少的内存。