如何制作通用平均方法,以便您可以在其中放入任何类型?

How to make a Generic average method, so that you can put any type in it?

我试着做一个通用的平均法。这样该方法就可以与任何类型进行交互。但 any 类型的值也必须是通用的。这样你就可以拥有以下类型:int、float、decimal。

我这样试:

public class Calculator<T>
    {
        public T Average(List<T>items, Func<T, T>  getValue )
        {

            T sum = 0 ;

            foreach (var item in items)
            {
                sum += getValue(item);
            }

            return (T) Convert.ChangeType(sum / items.Count(), typeof(T));
        }
    }
}

我有一个这样的例子 class:

public  class Product<T>
    {

        public T Weight { get; set; }

    }

但是我已经在这一行得到一个错误:

   T sum = 0 ;

Cannot implicitly convert type 'int' to 'T'

和程序 class:


            var listProducts = new List<Product<int>> { 
                    new Product<int>{ Weight = 1},
                    new Product<int> { Weight = 2},
                    new Product<int> { Weight = 87}
            };
            var calc2 = new Calculator<Product<int>>();
            var averageWeight = calc2.Average(listProducts, p => p.Weight);

            Console.WriteLine($"Average weight is: {averageWeight}" );

我现在是这样的:

public class Calculator<T> where T: class
    {
        public T Average(List<T>items, Func<T, T>  getValue )
        {

            T sum = default(T);

            foreach (var item in items)
            {
                sum += getValue(item);
            }

            return (sum / items.Count());
        }
    }

但是我得到这个错误:

'+=' cannot be applied to operands of type 'T' and 'T'

在线:

sum += getValue(item);

尝试按照以下声明默认值

T sum = default(T);

如果您只使用数值类型,那么使用泛型类型约束进行计算也是有意义的

where S : struct, IComparable, IComparable<S>, IConvertible, IEquatable<S>, IFormattable

此外,您将 p => p.Weight 作为 Func<T, T> getValue 传递,这是不正确的,您应该为 Func<T, TResult> 中的 return 值声明额外的泛型类型参数,目前您接受和return相同的类型

最后,我通过添加一个额外的通用参数并将 sum 设置为 dynamic 以避免编译时错误,使您的代码段正常工作

public class Program
{
    static void Main(string[] args)
    {
        var listProducts = new List<Product<int>> {
            new Product<int> { Weight = 1},
            new Product<int> { Weight = 2},
            new Product<int> { Weight = 87}
        };
        var calc2 = new Calculator<Product<int>, int>();
        var averageWeight = calc2.Average(listProducts, p => p.Weight);

        Console.WriteLine($"Average weight is: {averageWeight}");
    }
}

public class Calculator<T, S> where S : struct, IComparable, IComparable<S>, IConvertible, IEquatable<S>, IFormattable
{
    public S Average(List<T> items, Func<T, S> getValue)
    {
        dynamic sum = default(S);

        foreach (var item in items)
        {
            var result = getValue(item);
            sum += result;
        }

        return (S)Convert.ChangeType(sum / items.Count, typeof(S));
    }
}

它打印

Average weight is: 30

在您的代码段中,Product<int> 作为 Calculator 的通用类型参数,而 intProduct<T> 的通用类型参数,您不能将它们作为一个getValue 和 return 中的参数从 Average

返回