C# - 如何获取传递的 lambda 表达式的值

Posted

技术标签:

【中文标题】C# - 如何获取传递的 lambda 表达式的值【英文标题】:C# - How to get the value of a passed lambda expression 【发布时间】:2021-09-13 18:49:01 【问题描述】:

我有一个特殊情况。我需要重写一个库,但我没有原始代码。为了让讨论更清楚,让我们调用库 HandlerLibOld 和 HandlerLibNew。

我想制作 HandlerLibNew 来代替 HandlerLibOld。

我有一个使用这个库的应用程序,它是一个有 1000 次调用库的大型应用程序。 我宁愿不必更改应用程序代码。

示例应用程序代码

public class MyMessage : MyBaseClass

   public int ValueA get;set;
   public int ValueB get;set;

public class MyOtherMessage : MyBaseClass

   public int ValueC get;set;
   public int ValueD get;set;


public class Sender

   Handler handler = new Handler();
   handler.Send<MyMessage>(m =>  m.ValueA=10; m.ValueB=20; );

注意handler.Send&lt;MyMessage&gt;(m =&gt; m.ValueA=10; m.ValueB=20; ); 这一行。它使用 lambda 表达式来定义 MyMessage 的对象并设置该对象的两个属性。请注意,我宁愿不必更改此代码。

也许我误解了 lambda 表达式的作用,但重点是我需要告诉 Handler.Send 值 ValueA 和 ValueB。

现在我想编写HandlerSend 方法的实现。棘手的部分是 lambda 表达式使它成为一个动作,但我想获取 MyMessage 对象实例。我怎样才能做到这一点?我需要以某种方式使用反射吗?

我的尝试

我试过了:

public class Handler

    public void Send<T>(Action<T> actionmessage)
    
        // actionmessage is an object of type Action<T>, 
        // I want to get the object of type T that was passed into the method.
    

我也试过了:

public class Handler

    public void Send<T>(T message)
    
         // This will not compile. I get:
         //    Cannot convert lambda expression 
         //    to type 'object' because it is not a delegate type
    

我知道这是可能的,因为它适用于 HandlerLibOld。如何使用 HandlerLibNew 实现相同的目标?我无权访问 HandlerLibOld 的代码。

【问题讨论】:

actionmessage 可以对传入的对象做任何喜欢的事情;您无法控制它,也无法(轻松)反映它,因为代码是编译的 IL。唯一可以合理使用它的就是调用它 (actionmessage(message))。您可以将委托包装在自己的内部,以便在调用委托之前或之后执行操作,仅此而已。至于调用它的方式、原因和时间(即当你得到message 时),仅从界面无法确定。 【参考方案1】:

为了使该操作起作用,您必须以 T 实例开头:

public void Send<T>(Action<T> actionMessage)
        where T: new()
    
        var input = new T();
        actionMessage(input);
        //T has now valueA and valueB populated
        //do more with input T
        //send
    

现在,如果 T 有一个约束,例如实现某个接口,您可以在对象本身上做更多的事情。如果您使用基类,则必须小心对象切片。

【讨论】:

完美!正是我想要的!谢谢!

以上是关于C# - 如何获取传递的 lambda 表达式的值的主要内容,如果未能解决你的问题,请参考以下文章

C# 将 Lambda 表达式作为方法参数传递

如何在 lambda 表达式中传递变量?

Lambda 表达式以及如何组合它们?

C# 多线程传递多个参数

C#中 Lambda表达式 与正则表达式的关系

传递给这个lambda表达式的值是多少?