Is there a constraint that restricts my generic method to numeric types?

后端 未结 21 2606
栀梦
栀梦 2020-11-21 05:48

Can anyone tell me if there is a way with generics to limit a generic type argument T to only:

  • Int16
  • Int32
21条回答
  •  名媛妹妹
    2020-11-21 06:37

    Workaround using policies:

    interface INumericPolicy
    {
        T Zero();
        T Add(T a, T b);
        // add more functions here, such as multiplication etc.
    }
    
    struct NumericPolicies:
        INumericPolicy,
        INumericPolicy
        // add more INumericPolicy<> for different numeric types.
    {
        int INumericPolicy.Zero() { return 0; }
        long INumericPolicy.Zero() { return 0; }
        int INumericPolicy.Add(int a, int b) { return a + b; }
        long INumericPolicy.Add(long a, long b) { return a + b; }
        // implement all functions from INumericPolicy<> interfaces.
    
        public static NumericPolicies Instance = new NumericPolicies();
    }
    

    Algorithms:

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

    Usage:

    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.
    

    The solution is compile-time safe. CityLizard Framework provides compiled version for .NET 4.0. The file is lib/NETFramework4.0/CityLizard.Policy.dll.

    It's also available in Nuget: https://www.nuget.org/packages/CityLizard/. See CityLizard.Policy.I structure.

提交回复
热议问题