什么时候优先选择lambda表达式中的参数?

本文关键字:参数 表达式 lambda 选择 什么时候 | 更新日期: 2023-09-27 18:16:33

这是一个奇怪的问题,但它出现了一天,它让我思考。

什么时候使用这种形式的lambda表达式是更好的设计?(x => x.Whatever)"的诗句 ".(() => obj.Whatever)"。

考虑以下扩展方法。

public static class ExtensionMethods
{
    public static string TryToGetTheString<T>(this T value, Func<T, string> method)
    {
        try
        {
            return method(value);
        }
        catch (Exception)
        {
            return "banana";
        }
    }
    public static string TryToGetTheStringTwo<T>(this T value, Func<string> method)
    {
        try
        {
            return method();
        }
        catch (Exception)
        {
            return "banana";
        }
    }
 }

和下面的自引用类。

 public class testClass5000
 {
     private int? _id;
     public int? ID { get { return _id; } set { _id = value; } }
     private string _urgh;
     public string Urgh { get; set; }
     public testClass5000 tc5k { get; set; }
 }

然后使用一个非常懒惰的进程来避免检查null,同时尝试从testClass5000获取字符串(唔),您可以实现如下扩展方法和类:

    private void main()
    {
        var tc = new testClass5000();
        textBox1.text = tc.TryToGetTheString(x => x.tc5k.tc5k.tc5k.Urgh);
    }

但是,由于tc是在本地声明的,下面的语句也适用。

    private void main()
    {
        var tc = new testClass5000();
        textBox1.text = tc.TryToGetTheStringTwo(() => tc.tc5k.tc5k.tc5k.Urgh);
    }

我很好奇什么时候(x => x.tc5k.tc5k.tc5k.Urgh)是必要的,什么时候(() => tc.tc5k.tc5k.tc5k.Urgh)更可取。

//////////////////////////////////////////

我确实想到了下面的场景,其中传递参数似乎更可取。

使用以下扩展方法。

public static class ExtensionMethods
{
    public static T TestOne<T>(this T value, Func<T, T> method)
    {
        try
        {
            return method(value);
        }
        catch (Exception)
        {
            return default(T);
        }
    }
    public static T TestTwo<T>(this T value, Func<T> method)
    {
        try
        {
            return method();
        }
        catch (Exception)
        {
            return default(T);
        }
    }
}

并使用以下代码。

    private void Form1_Load(object sender, EventArgs e)
    {
        var firstValue = 5;
        var secondValue = 10;
        var resultOne = firstValue.TestOne(x => x + 1).TestOne(x => x * 2);
        //returns 12
        var resultTwo = secondValue.TestTwo(() => secondValue + 1).TestTwo(() => secondValue * 2);
        //returns 20
        var resultThree = secondValue.TestTwo(() => secondValue.TestTwo(() => secondValue + 1) * 2);
        //returns 22
    }

在这个例子中。testone (x => x + 1). testone (x => x * 2)是更好的符号,因为要在不传递参数的情况下实现相同的功能,您需要开始嵌套表达式。

什么时候优先选择lambda表达式中的参数?

直接在lambda中注入参数值的代价更高,因为编译器必须为此创建一个特殊的类。

如果我们排除性能方面的考虑,那么我会说注入参数更容易编写(这里是个人偏好),并且在原型中保留参数((x,y) =>//做某事)在实际上不是提供参数值的人时是有用的。例如,当使用Select Linq查询时。或者我经常在负载平衡场景中使用它(一个lambda "service => service. somefunction()",然后一个特殊的工厂检索服务并执行lambda)。

在参数与您提供的原始值不相同的情况下

一个粗略的例子

public static class Extensions
{
    public static void DoSomething(this string s,Action<string> action)
    {
        var something = Enumerable.Range(1,100).Select(i=> String.Format("{0}_{1}",s,i));
        foreach (var ss in something)
        {
            action(ss);
        }
    }
}
然后

var something = "ABC123";
something.DoSomething(x=>Console.WriteLine(x));
//Ignoring that we could do something.DoSomething(Console.WriteLine);

显然,如果没有参数,您就无法访问您感兴趣的实际值,并且原始值在此概念中没有任何用处。