有人能告诉我是否有一种方法可以用泛型将泛型类型参数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
当前回答
话题老了,但对未来的读者来说:
这个特性与歧视联盟紧密相关,而歧视联盟目前还没有在c#中实现。我发现它的问题在这里:
https://github.com/dotnet/csharplang/issues/113
这个问题仍然没有解决,并且已经计划在c# 10中推出新特性
所以我们仍然需要等待一段时间,但在释放之后,你可以这样做:
static bool IntegerFunction<T>(T value) where T : Int16 | Int32 | Int64 | ...
其他回答
这是没有限制的。对于任何想要使用泛型进行数值计算的人来说,这都是一个真正的问题。
更进一步说,我们需要
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。
您可以在运行时应用该限制(通过对操作符进行反射或检查类型),但这首先就失去了使用泛型的优势。
所有数值类型都是实现IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable的结构体。然而,DateTime也是如此。
所以这个泛型扩展方法是可能的:
public static bool IsNumeric<T>(this T value) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable =>
typeof(T) != typeof(DateTime);
但是对于实现这些接口的结构体,它将失败,例如:
public struct Foo : IComparable, IComparable<Foo>, IConvertible, IEquatable<Foo>, IFormattable { /* ... */ }
这个非泛型的替代方法性能较差,但保证可以工作:
public static bool IsNumeric(this Type type) =>
type == typeof(sbyte) || type == typeof(byte) ||
type == typeof(short) || type == typeof(ushort) ||
type == typeof(int) || type == typeof(uint) ||
type == typeof(long) || type == typeof(ulong) ||
type == typeof(float) ||
type == typeof(double) ||
type == typeof(decimal);
我想知道和samjudson一样,为什么只对整数有效?如果是这样的话,你可能想要创建一个helper类或者类似的东西来保存你想要的所有类型。
如果你想要的只是整数,不要使用泛型,那不是泛型;或者更好的是,通过检查其类型来拒绝任何其他类型。
话题老了,但对未来的读者来说:
这个特性与歧视联盟紧密相关,而歧视联盟目前还没有在c#中实现。我发现它的问题在这里:
https://github.com/dotnet/csharplang/issues/113
这个问题仍然没有解决,并且已经计划在c# 10中推出新特性
所以我们仍然需要等待一段时间,但在释放之后,你可以这样做:
static bool IntegerFunction<T>(T value) where T : Int16 | Int32 | Int64 | ...
我会使用一个通用的,你可以处理外部…
/// <summary>
/// Generic object copy of the same type
/// </summary>
/// <typeparam name="T">The type of object to copy</typeparam>
/// <param name="ObjectSource">The source object to copy</param>
public T CopyObject<T>(T ObjectSource)
{
T NewObject = System.Activator.CreateInstance<T>();
foreach (PropertyInfo p in ObjectSource.GetType().GetProperties())
NewObject.GetType().GetProperty(p.Name).SetValue(NewObject, p.GetValue(ObjectSource, null), null);
return NewObject;
}