Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
扩展方法Average()C#_C#_.net - Fatal编程技术网

扩展方法Average()C#

扩展方法Average()C#,c#,.net,C#,.net,首先,你们需要知道我不想使用C#中的LINQ库 现在我想写一个扩展方法,返回不同列表的平均值。这是名单 integers = new List<int> { 5, 76, 3, 93, 143, 5, 11, 67, 5 }; doubles = new List<double> { 1.23, 68.256, 44.55, 96.127, 393.4567, 2.45, 4.1 }; persons = new List<Person> { new P

首先,你们需要知道我不想使用C#中的LINQ库

现在我想写一个扩展方法,返回不同列表的平均值。这是名单

integers = new List<int> { 5, 76, 3, 93, 143, 5, 11, 67, 5 };
doubles = new List<double> { 1.23, 68.256, 44.55, 96.127, 393.4567, 2.45, 4.1 };
persons = new List<Person>
{
   new Person {Firstname = "John", Lastname = "last", Age = 66, Sallary = 1513},
   new Person {Firstname = "Donald", Lastname = "last", Age = 77, Sallary = 3100}
};

首先,
Average
方法返回的整数列表结果错误,因为您使用的是整数除法(它返回的是
45
而不是
45.3333

要使其与double一起工作,您需要使用
IEnumerable
等创建一个重载

public static double Average(this IEnumerable<double> source)
{
    IList<double> list = source as IList<double>;

    if (source == null || source.Count == 0)
        throw new ArgumentNullException("Err");

    double sum = 0;

    for (int i = 0; i < list.Count; i++)
    {
        sum += list[i];
    }

    return sum / list.Count;
}

我们可以利用c#中的泛型类型来找到平均值。这允许我们只使用一种方法来计算整数和double

 public static double Average<T>(this List<T> source)
    {
        IList<T> list = source as IList<T>;
        if (source == null)
            throw new ArgumentNullException("Err");
        if(source.GetType() == typeof(List<int>) || source.GetType() == typeof(List<double>))
        {
            double sum = 0;
            for (int i = 0; i < list.Count; i++)
            {
                sum += Convert.ToDouble((object)list[i]);
            }
            return sum / list.Count;
        }
        else
        {
            throw new InvalidOperationException("Not possible to find average");
        }
    }
公共静态双平均(此列表源)
{
IList list=源作为IList;
if(source==null)
抛出新的ArgumentNullException(“Err”);
if(source.GetType()==typeof(List)| source.GetType()==typeof(List))
{
双和=0;
for(int i=0;i
并调用该方法

var integers = new List<int> { 5, 76, 3, 93, 143, 5, 11, 67, 5 };
        var doubles = new List<double> { 1.23, 68.256, 44.55, 96.127, 393.4567, 2.45, 4.1 };
        Console.WriteLine(doubles.Average());
        Console.WriteLine(integers.Average());
var integers=新列表{5,76,3,93,143,5,11,67,5};
var doubles=新列表{1.23,68.256,44.55,96.127,393.4567,2.45,4.1};
Console.WriteLine(doubles.Average());
Console.WriteLine(integers.Average());

就像我在评论中写的那样,您可以使用Linq存储库中的实现。我刚刚改变了他们处理0个项目的方式

    public static double Average(this IEnumerable<int> source)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        long sum = 0;
        long count = 0;
        checked
        {
            foreach (int v in source)
            {
                sum += v;
                count++;
            }
        }
        if (count == 0)
        {
            return 0;
        }
        return (double)sum / count;
    }

    public static double Average<T>(this IEnumerable<T> source)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }
        if(typeof(T) != typeof(int)
            && typeof(T) != typeof(double)
            && typeof(T) != typeof(float)
            && typeof(T) != typeof(decimal)
            && typeof(T) != typeof(long))
        {
            throw new InvalidOperationException($"Wrong type specified: {typeof(T)}");
        }

        double sum = 0;
        long count = 0;
        checked
        {
            foreach (T v in source)
            {
                sum += Convert.ToDouble(v);
                count++;
            }
        }
        if (count == 0)
        {
            return 0;
        }
        return (double)sum / count;
    }
公共静态双平均(此IEnumerable源)
{
if(source==null)
{
抛出新ArgumentNullException(nameof(source));
}
长和=0;
长计数=0;
选中的
{
foreach(源代码中的int v)
{
总和+=v;
计数++;
}
}
如果(计数=0)
{
返回0;
}
返回(双)和/计数;
}
公共静态双平均(此IEnumerable源)
{
if(source==null)
{
抛出新ArgumentNullException(nameof(source));
}
if(typeof(T)!=typeof(int)
&&类型(T)!=类型(双)
&&typeof(T)!=typeof(float)
&&typeof(T)!=typeof(十进制)
&&类型(T)!=类型(长)
{
抛出新的InvalidOperationException($”指定的类型错误:{typeof(T)}”);
}
双和=0;
长计数=0;
选中的
{
foreach(源中的T v)
{
总和+=转换为二(v);
计数++;
}
}
如果(计数=0)
{
返回0;
}
返回(双)和/计数;
}
可以打开一个工作示例

当然,可以找到原始的Linq代码

我只能计算整数列表的平均值。我还想计算双重名单的平均数和我的人员名单的平均工资


正如一些用户的评论中已经提到的,最好将其提取到单独的例程中。正如Klaus上面提到的,
编译时检查总是比运行时检查好(更好的性能、更好的诊断和更早的诊断)
。我同意,但正如我在另一个答案中提到的,这是否意味着程序员的设计不好,或者作者的面向对象设计不好

这里有一个使用泛型(
)的小示例,一个例程执行
int
double
列表,另一个(对于
Person
)提取到它自己的例程中。第一个
Average
例程使用的帮助返回其值等于指定对象的指定类型

public static class Extensions
    {
        public static T Average<T>(this IEnumerable<T> source)
        {
            double dblSum = 0;
            int intSum = 0;

            if (source == null)
                throw new ArgumentNullException("Err");
            if (typeof(T) == typeof(int) && source is List<int> intList && intList.Count > 0)
            {
                for (int i = 0; i < intList.Count; i++)
                {
                    intSum += intList[i];
                }
                return (T)Convert.ChangeType((intSum / intList.Count), typeof(T));
            }
            else if (typeof(T) == typeof(double) && source is List<double> dblList && dblList.Count > 0)
            {
                for (int i = 0; i < dblList.Count; i++)
                {
                    dblSum += dblList[i];
                }
                return (T)Convert.ChangeType((dblSum / dblList.Count), typeof(T));
            }
            else
            {
                return default;
            }
        }

        public static int Average(this IEnumerable<Person> people)
        {
            int intSum = 0;
            if (people != null && people is List<Person> perList && perList.Count > 0)
            {
                for (int i = 0; i < perList.Count; i++)
                {
                    intSum += perList[i].Sallary;
                }
                return intSum / perList.Count;
            }
            else
            {
                return default;
                // throw new ArgumentNullException("Err");
            }

        }
    }
公共静态类扩展
{
公共静态T平均值(此IEnumerable源)
{
双dblSum=0;
int和=0;
if(source==null)
抛出新的ArgumentNullException(“Err”);
如果(typeof(T)=typeof(int)&&source是List intList&&intList.Count>0)
{
for(inti=0;i0),则为else
{
for(int i=0;i0)
{
for(int i=0;i
请注意:我不确定Sallary的类型,因为您的帖子中没有提供。您可能需要稍微更改
Average
例程(Person),以适应您的
Sallary
类型。

源代码,因为如果可枚举项实际上不是列表,IList
将返回
null
。最好只是迭代可枚举的usi
var integers = new List<int> { 5, 76, 3, 93, 143, 5, 11, 67, 5 };
        var doubles = new List<double> { 1.23, 68.256, 44.55, 96.127, 393.4567, 2.45, 4.1 };
        Console.WriteLine(doubles.Average());
        Console.WriteLine(integers.Average());
    public static double Average(this IEnumerable<int> source)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        long sum = 0;
        long count = 0;
        checked
        {
            foreach (int v in source)
            {
                sum += v;
                count++;
            }
        }
        if (count == 0)
        {
            return 0;
        }
        return (double)sum / count;
    }

    public static double Average<T>(this IEnumerable<T> source)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }
        if(typeof(T) != typeof(int)
            && typeof(T) != typeof(double)
            && typeof(T) != typeof(float)
            && typeof(T) != typeof(decimal)
            && typeof(T) != typeof(long))
        {
            throw new InvalidOperationException($"Wrong type specified: {typeof(T)}");
        }

        double sum = 0;
        long count = 0;
        checked
        {
            foreach (T v in source)
            {
                sum += Convert.ToDouble(v);
                count++;
            }
        }
        if (count == 0)
        {
            return 0;
        }
        return (double)sum / count;
    }
public static class Extensions
    {
        public static T Average<T>(this IEnumerable<T> source)
        {
            double dblSum = 0;
            int intSum = 0;

            if (source == null)
                throw new ArgumentNullException("Err");
            if (typeof(T) == typeof(int) && source is List<int> intList && intList.Count > 0)
            {
                for (int i = 0; i < intList.Count; i++)
                {
                    intSum += intList[i];
                }
                return (T)Convert.ChangeType((intSum / intList.Count), typeof(T));
            }
            else if (typeof(T) == typeof(double) && source is List<double> dblList && dblList.Count > 0)
            {
                for (int i = 0; i < dblList.Count; i++)
                {
                    dblSum += dblList[i];
                }
                return (T)Convert.ChangeType((dblSum / dblList.Count), typeof(T));
            }
            else
            {
                return default;
            }
        }

        public static int Average(this IEnumerable<Person> people)
        {
            int intSum = 0;
            if (people != null && people is List<Person> perList && perList.Count > 0)
            {
                for (int i = 0; i < perList.Count; i++)
                {
                    intSum += perList[i].Sallary;
                }
                return intSum / perList.Count;
            }
            else
            {
                return default;
                // throw new ArgumentNullException("Err");
            }

        }
    }