首先,你们都需要知道,我不想在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}
};这是我已经得到的:
public static double Average(this IEnumerable<int> source)
{
IList<int> list = source as IList<int>;
if (source == null) throw new ArgumentNullException("Err");
long sum = 0;
for (int i = 0; i < list.Count; i++)
{
sum += list[i];
}
return sum / list.Count;
}我只能计算我的整数列表的平均值。我还想计算双重列表的平均值和我的人员列表的平均工资。
这就是我将如何调用计算人员列表平均工资的函数
persons.Average(x => x.Sallary).ShowSingle("persons.Average(x => x.Sallary)");发布于 2020-11-22 21:03:04
首先,您的Average方法返回了错误的整数列表结果,因为您使用了整数除法(它返回45而不是45.3333)。
要使它与double一起工作,您需要创建一个使用IEnumerable<double>等的重载。
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;
}您可以通过使用foreach来简化该方法
public static double Average(this IEnumerable<double> source)
{
if (source == null)
throw new ArgumentNullException("Err");
double sum = 0;
int count = 0;
foreach (double entry in source)
{
sum += entry;
count+=1;
}
if (count == 0) return 0;
return sum / count;
}发布于 2020-11-22 22:40:25
就像我在评论中写的那样,您可以使用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;
}可以通过here打开一个工作示例
当然,原始的Linq代码可以在here中找到
发布于 2020-11-22 23:28:47
我只能计算我的整数列表的平均值。我还想计算双重列表的平均值和我的人员列表的平均工资。
正如一些用户在评论中提到的,最好将其提取到单独的例程中。就像克劳斯上面提到的,Compile-time checking is always better than run-time checking (better performance, better and earlier diagnostics)。我同意,但正如我在另一个答案中提到的,这是否意味着它是程序员的糟糕设计,还是作者的糟糕的面向对象设计?
下面是一个使用泛型的小示例(<T>),一个例程执行int和double列表,另一个例程(用于Person)提取到它自己的例程中。第一个Average例程使用Convert.ChangeType的帮助返回其值等于指定对象的指定类型。
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");
}
}
}请注意:我不确定Sallary的类型,因为你的帖子中没有提供这一点。您可能需要稍微更改Average例程(Person)以适应您的Sallary类型。
https://stackoverflow.com/questions/64954225
复制相似问题