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

Int16 Int32 Int64 UInt16 UInt32 UInt64

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

喜欢的东西:

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

当前回答

没有办法将模板限制为类型,但是可以根据类型定义不同的操作。作为泛型数值包的一部分,我需要一个泛型类来添加两个值。

    class Something<TCell>
    {
        internal static TCell Sum(TCell first, TCell second)
        {
            if (typeof(TCell) == typeof(int))
                return (TCell)((object)(((int)((object)first)) + ((int)((object)second))));

            if (typeof(TCell) == typeof(double))
                return (TCell)((object)(((double)((object)first)) + ((double)((object)second))));

            return second;
        }
    }

请注意,typeofs是在编译时计算的,因此if语句将被编译器删除。编译器还会删除虚假的类型转换。因此,在编译器中会解析为

        internal static int Sum(int first, int second)
        {
            return first + second;
        }

其他回答

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

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

.NET 6有一个预览功能:

https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/#generic-math

下面是文章中的一个例子:

static T Add<T>(T left, T right)
    where T : INumber<T>
{
    return left + right;
}

INumber是一个实现其他接口的接口,比如IAdditionOperators,它允许通用的+用法。现在这是可能的,因为另一个预览特性是接口中的静态抽象,因为+操作符重载是一个静态方法:

/// <summary>Defines a mechanism for computing the sum of two values.</summary>
/// <typeparam name="TSelf">The type that implements this interface.</typeparam>
/// <typeparam name="TOther">The type that will be added to <typeparamref name="TSelf" />.</typeparam>
/// <typeparam name="TResult">The type that contains the sum of <typeparamref name="TSelf" /> and <typeparamref name="TOther" />.</typeparam>
[RequiresPreviewFeatures(Number.PreviewFeatureMessage, Url = Number.PreviewFeatureUrl)]
public interface IAdditionOperators<TSelf, TOther, TResult>
    where TSelf : IAdditionOperators<TSelf, TOther, TResult>
{
    /// <summary>Adds two values together to compute their sum.</summary>
    /// <param name="left">The value to which <paramref name="right" /> is added.</param>
    /// <param name="right">The value which is added to <paramref name="left" />.</param>
    /// <returns>The sum of <paramref name="left" /> and <paramref name="right" />.</returns>
    static abstract TResult operator +(TSelf left, TOther right);
}

我会使用一个通用的,你可以处理外部…

/// <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;
}

使用策略的解决方案:

interface INumericPolicy<T>
{
    T Zero();
    T Add(T a, T b);
    // add more functions here, such as multiplication etc.
}

struct NumericPolicies:
    INumericPolicy<int>,
    INumericPolicy<long>
    // add more INumericPolicy<> for different numeric types.
{
    int INumericPolicy<int>.Zero() { return 0; }
    long INumericPolicy<long>.Zero() { return 0; }
    int INumericPolicy<int>.Add(int a, int b) { return a + b; }
    long INumericPolicy<long>.Add(long a, long b) { return a + b; }
    // implement all functions from INumericPolicy<> interfaces.

    public static NumericPolicies Instance = new NumericPolicies();
}

算法:

static class Algorithms
{
    public static T Sum<P, T>(this P p, params T[] a)
        where P: INumericPolicy<T>
    {
        var r = p.Zero();
        foreach(var i in a)
        {
            r = p.Add(r, i);
        }
        return r;
    }

}

用法:

int i = NumericPolicies.Instance.Sum(1, 2, 3, 4, 5);
long l = NumericPolicies.Instance.Sum(1L, 2, 3, 4, 5);
NumericPolicies.Instance.Sum("www", "") // compile-time error.

该解决方案是编译时安全的。CityLizard框架提供了。net 4.0的编译版本。文件名为“lib/NETFramework4.0/ citylizad . policy .dll”。

它也可以在Nuget: https://www.nuget.org/packages/CityLizard/。参见CityLizard.Policy.I结构。

没有办法将模板限制为类型,但是可以根据类型定义不同的操作。作为泛型数值包的一部分,我需要一个泛型类来添加两个值。

    class Something<TCell>
    {
        internal static TCell Sum(TCell first, TCell second)
        {
            if (typeof(TCell) == typeof(int))
                return (TCell)((object)(((int)((object)first)) + ((int)((object)second))));

            if (typeof(TCell) == typeof(double))
                return (TCell)((object)(((double)((object)first)) + ((double)((object)second))));

            return second;
        }
    }

请注意,typeofs是在编译时计算的,因此if语句将被编译器删除。编译器还会删除虚假的类型转换。因此,在编译器中会解析为

        internal static int Sum(int first, int second)
        {
            return first + second;
        }