扩展方法Average()C#
首先,你们需要知道我不想使用C#中的LINQ库 现在我想写一个扩展方法,返回不同列表的平均值。这是名单扩展方法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
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");
}
}
}