如何从 lambda 表达式获取引用实例的实例
我有这个 lambda 表达式 Expression
然后我用一个方法传递一个类的实例:
_commandExecuter.ProcessCommand (() => aClass.Method())
How do I get the instance of aClass
inside the ProcessCommand
method?
我想执行此类的一些附加方法或获取一些属性值。
这可能吗?
编辑: 我现在已经编写了一个简单的静态帮助器方法来获取实例:
private static object GetReferredProviderInstance(Expression body)
{
var methodCallExpression = body as MethodCallExpression;
if (methodCallExpression != null)
{
var constantExpression = methodCallExpression.Object as ConstantExpression;
if (constantExpression != null) return constantExpression.Value;
}
return null;
}
方法调用如下所示...
Expression body = commandToExecute.Body; // this is the method parameter Expression<Func<bool>> commandToExecute
var referredProviderInstance = GetReferredProviderInstance(body);
这里的问题是,对 ConstantExpression 的转换结果为 Null
。因此,constantExpression
始终为 null。
有什么想法吗?
编辑2 我解决了问题......
private static object GetReferredProviderInstance(Expression body)
{
var methodCallExpression = body as MethodCallExpression;
if (methodCallExpression != null)
{
var memberExpression = methodCallExpression.Object as MemberExpression;
if (memberExpression != null)
{
var constantExpression = memberExpression.Expression as ConstantExpression;
if (constantExpression != null) return constantExpression.Value;
}
}
return null;
}
但又出现了一个新问题。我只获取我的提供程序的引用实例所在的 Windows 窗体的实例。
如何获取 lambda 表达式的真实对象 (aClass
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这实际上是可能的,但这取决于您传递给该方法的内容。假设您有这样的场景,将所在类的实例方法传递给 ProcessCommand:
那么您可以使用以下 ProcessCommand 方法。仅当在此实例上调用
MethodToCall
时,此方法才有效。更复杂的场景如下:
我们调用的方法现在位于另一个类中,并且不是在此实例上调用,而是在名为
usedClass
的CalledClass
实例上调用。但是编译器如何将usedClass
变量传递到 lambda 表达式中呢?没有任何内容定义可以调用方法MethodToCall
的字段usedClass
。编译器通过生成一个内部类来解决这个问题,该内部类具有一个名为
usedClass
的字段。结果,ProcessCommand
方法现在变成这样:稍微复杂一些,因为编译器必须生成一个匿名内部类。
This is actually possible but it depends on what you pass into this method. Suppose you have the scenario where you pass an instance method of the class that you are in to
ProcessCommand
:Then you can use the following
ProcessCommand
method. This only works becauseMethodToCall
is called on this instance.The more complicated scenario is as follows:
The method we are calling is now in another class and isn't called on this instance but on an instance of
CalledClass
calledcalledClass
. But how does the compiler pass thecalledClass
variable into the lambda expression? There is nothing that defines a fieldcalledClass
that the methodMethodToCall
can be called on.The compiler solves this by generating an inner class with one field with the name
calledClass
. As a result theProcessCommand
method now becomes this:Slightly more complicated because the compiler has to generate an anonymous inner class.
不可能“开箱即用”,您也许可以通过反射来破解某些东西,但这并不可取,这会非常落后。编辑:根据罗纳德的说法,实际上是可能的,但仍然相当落后。像这样隐藏的副作用使代码难以阅读和维护。
相反,您的 ProcessCommand 应该采用整个
aClass
对象,或更佳的是带有.Method()
的IMyCommand
接口以及.Method()
的附加方法和属性代码>ProcessCommand需要。那么aClass.GetType()
类型应该实现IMyCommand
。It is not possible "out of the box", you may be able to hack something with reflection,but that is not advisable, it will be very backwards.Edit: Actually possible according to Ronald, but still quite backwards. Hidden side effects like this make the code hard to read and maintain.
Instead your ProcessCommand should take either the whole
aClass
object or more preferably anIMyCommand
interface with.Method()
and the additional methods and properties thatProcessCommand
needs. Then theaClass.GetType()
type should implementIMyCommand
.