有人能告诉我是否有一种方法可以用泛型将泛型类型参数T限制为:
Int16 Int32 Int64 UInt16 UInt32 UInt64
我知道哪里关键字,但不能找到只有这些类型的接口,
喜欢的东西:
static bool IntegerFunction<T>(T value) where T : INumeric
有人能告诉我是否有一种方法可以用泛型将泛型类型参数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>
对于如此特定的内容,为什么不为每种类型设置重载呢?列表很短,而且可能占用更少的内存。