【发布时间】: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<MyMessage>(m => { m.ValueA=10; m.ValueB=20; }); 这一行。它使用 lambda 表达式来定义 MyMessage 的对象并设置该对象的两个属性。请注意,我宁愿不必更改此代码。
也许我误解了 lambda 表达式的作用,但重点是我需要告诉 Handler.Send 值 ValueA 和 ValueB。
现在我想编写Handler 的Send 方法的实现。棘手的部分是 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时),仅从界面无法确定。