C# 扩展方法,通用列表上的SumIf<;T>;

C# 扩展方法,通用列表上的SumIf<;T>;,c#,list,generics,extension-methods,sum,C#,List,Generics,Extension Methods,Sum,我需要为List(T)编写一个通用扩展方法,该方法有条件地考虑T的每个字符串属性,然后在满足条件的情况下对T的相应十进制属性求和。我迄今为止的努力: // foreach(p in Persons) { if(p.Name == "mort"){sum p.Amount;} } public static double SumIf<T>(this T o, List<T> ListItems, string targetStr, ?strVals?

我需要为List(T)编写一个通用扩展方法,该方法有条件地考虑T的每个字符串属性,然后在满足条件的情况下对T的相应十进制属性求和。我迄今为止的努力:

// foreach(p in Persons) { if(p.Name == "mort"){sum p.Amount;} }

public static double SumIf<T>(this T o, List<T> ListItems, 
          string targetStr, ?strVals?, ?dblVals?)
{
    double sum = 0;
    foreach(T item in ListItems)
    {
        if(item.?strVal? == targetStr){ sum += item.?dblVal? ; }
    }
    return sum;
}
//foreach(p个人){if(p.Name==“mort”){sum p.Amount;}
公共静态双SumIf(此命令,列出列表项,
字符串targetStr、?strVals、?dblVals?)
{
双和=0;
foreach(ListItems中的T项)
{
如果(item.?strVal?==targetStr){sum+=item.?dblVal?;}
}
回报金额;
}
谢谢你的指导,
mort

听起来您想要一种提取字符串属性和double属性的方法(假设帖子中的“decimal”是打字错误,而不是代码中的“double”)
Func在这里是合适的:

public static double SumIf<T>(this IEnumerable<T> source, 
          string targetText,
          Func<T, string> textSelector,
          Func<T, double> valueSelector)
{
    double sum = 0;
    foreach (T item in source)
    {
        if (textSelector(item) == targetText)
        {
            sum += valueSelector(item);
        }
    }
    return sum;
}
。。。这对我来说就像:

double sum = list.SumIf("mort", x => x.Name, x => x.Amount);
。。。但它的灵活性要大得多

正如评论中提到的,你真的需要这个吗?您是否在足够的地方使用它,使简单的Where/Sum调用变得难以忍受?见鬼,您可以使用条件运算符将其转换为一个
Sum
调用:

double sum = list.Sum(x => x.Name == "mort" ? x => x.Amount : 0d);

听起来您想要一种提取string属性和double属性的方法(假设帖子中的“decimal”是打字错误,而不是代码中的“double”)-
Func
在这里是合适的:

public static double SumIf<T>(this IEnumerable<T> source, 
          string targetText,
          Func<T, string> textSelector,
          Func<T, double> valueSelector)
{
    double sum = 0;
    foreach (T item in source)
    {
        if (textSelector(item) == targetText)
        {
            sum += valueSelector(item);
        }
    }
    return sum;
}
。。。这对我来说就像:

double sum = list.SumIf("mort", x => x.Name, x => x.Amount);
。。。但它的灵活性要大得多

正如评论中提到的,你真的需要这个吗?您是否在足够的地方使用它,使简单的Where/Sum调用变得难以忍受?见鬼,您可以使用条件运算符将其转换为一个
Sum
调用:

double sum = list.Sum(x => x.Name == "mort" ? x => x.Amount : 0d);

您为方法引入了一些非常特定的约束,使其不能是泛型的,例如,T必须具有属性值。最好将这些依赖项作为函数传入:

public static double SumIf<T>(this IList<T> source, 
                              Func<T, bool> pred, 
                              Func<T, double> val) 
{
    double sum = 0;
    foreach (var item in source)
        if (pred(item))
            sum += val(item);

    return sum;
}
publicstaticdouble-SumIf(此IList源代码,
Func pred,
Func val)
{
双和=0;
foreach(源中的var项)
if(预测(项目))
总和+=val(项目);
回报金额;
}
然后,您可以将谓词和求和属性选择器作为lambdas传入:

List<Person> people = new List<Person>();
people.Add(new Person() { Name = "Joe", Amount =20.2});
people.Add(new Person() { Name = "Fred", Amount = 11 });
people.Add(new Person() { Name = "Joe", Amount = 5.7 });

double sum = people.SumIf(x => x.Name == "Joe", x => x.Amount);
List people=newlist();
添加(newperson(){Name=“Joe”,Amount=20.2});
添加(newperson(){Name=“Fred”,Amount=11});
添加(newperson(){Name=“Joe”,Amount=5.7});
double sum=people.SumIf(x=>x.Name==“Joe”,x=>x.Amount);

您为方法引入了一些非常具体的约束,使其不能是泛型的,例如,T必须有一个属性值。最好将这些依赖项作为函数传入:

public static double SumIf<T>(this IList<T> source, 
                              Func<T, bool> pred, 
                              Func<T, double> val) 
{
    double sum = 0;
    foreach (var item in source)
        if (pred(item))
            sum += val(item);

    return sum;
}
publicstaticdouble-SumIf(此IList源代码,
Func pred,
Func val)
{
双和=0;
foreach(源中的var项)
if(预测(项目))
总和+=val(项目);
回报金额;
}
然后,您可以将谓词和求和属性选择器作为lambdas传入:

List<Person> people = new List<Person>();
people.Add(new Person() { Name = "Joe", Amount =20.2});
people.Add(new Person() { Name = "Fred", Amount = 11 });
people.Add(new Person() { Name = "Joe", Amount = 5.7 });

double sum = people.SumIf(x => x.Name == "Joe", x => x.Amount);
List people=newlist();
添加(newperson(){Name=“Joe”,Amount=20.2});
添加(newperson(){Name=“Fred”,Amount=11});
添加(newperson(){Name=“Joe”,Amount=5.7});
double sum=people.SumIf(x=>x.Name==“Joe”,x=>x.Amount);

上述方法会给您带来什么问题?不适合您?还是紧随其后?或者你想要一个助手扩展方法?上面的方法给你带来了什么问题?不适合你?还是紧随其后?或者您想要一个助手扩展方法?除了在第二个实现中调用Select并将列表类型更改为string,因此无法为T列表调用Sum之外,一切都很好。除了在第二个实现中调用Select并将列表类型更改为string,因此无法为T列表调用Sum之外,一切都很好。