【问题标题】:Can I remove the need for the double lambda in this generic expression?我可以在这个泛型表达式中消除对双 lambda 的需要吗?
【发布时间】:2019-10-17 13:28:09
【问题描述】:

我已经做了这个扩展方法(我知道现在没有异常检查等,一旦我确定函数实际上是正确的就会添加):

public static IEnumerable<TSource> ChangeProperty<TSource, TResult>(this IEnumerable<TSource> source,Expression<Func<TSource,TResult>> res, Func<TSource, TResult> changeProp)
    {
        Type type = typeof(TSource);
        MemberExpression member = res.Body as MemberExpression;
        var name = member.Member.Name;

        foreach (var x in source)
        {
            var prop = type.GetProperty(name);
            prop.SetValue(x, changeProp(x));
            Console.WriteLine(prop.GetValue(x));
        }
        return source;
    }

并且在这种情况下使用(删除不需要的标签会从字符串中去除html标签):

_dc.EmailTemplates
.ChangeProperty(x=>x.Body,z=>RemoveUnwantedTags(z.Body))
.ToList();

但我不喜欢我必须使用双 lambda,一个用于获取属性名称,然后一个用于执行函数。我不知道是我对 Expression 的工作原理缺乏了解,还是我遗漏了一些非常明显但非常感谢您的帮助!

【问题讨论】:

  • 只做foreach (var x in ...) x.Body = RemoveUnwantedTags(x.Body); } 或类似的东西不是更简单吗?不需要反射、lambda 等
  • 我同意@canton7,但我也知道 lambdas 目前是主流..
  • 如果你真的想要,你可以定义例如一个Tap 方法,然后做_dc.EmailTemplates.Tap(x =&gt; x.Body = RemoveUnwantedTags(x.Body)).ToList(),但这开始有点味道,并且由于Linq 的懒惰性质可能会咬人
  • (另外,将type.GetProperty(name) above 放在foreach 循环中——相对而言,它非常昂贵,并且不依赖于x。)
  • 然后考虑类似于我上面描述的Tap 方法。 c.SomeMethod(x =&gt; x.Body = RemoveUnwantedTags(x.Body)) 肯定比 c.SomeMethod(x =&gt; x.Body, x =&gt; RemoveUnwatedTags(x.Body)) 好?

标签: c# lambda reflection extension-methods


【解决方案1】:

类似于ForEachList&lt;T&gt; 中的使用方式,所需的功能可以简化为

public static IEnumerable<TSource> Apply<TSource>(this IEnumerable<TSource> source, Action<TSource> action) {
    foreach (var item in source) {
        action(item);
        yield return item;            
    }        
}

使用过

_dc.EmailTemplates
    .Apply(x => x.Body = RemoveUnwantedTags(x.Body))
    .ToList();

这也可以用于多个成员

_dc.EmailTemplates
    .Apply(x => {
        x.Body = RemoveUnwantedTags(x.Body);
        x.SomeOtherMember = SomeOtherFunction(x.SomeOtherMember);
    })
    .ToList();

【讨论】:

    猜你喜欢
    • 2016-04-25
    • 2017-06-15
    • 1970-01-01
    • 2011-04-21
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多