我怎样才能对象实例从()=> foo.Title表达 [英] How can I get object instance from ()=>foo.Title expression
问题描述
我有一个简单的类属性。
I have a simple class with a property
class Foo
{
string Title { get; set; }
}
我试图简化调用一个函数,像
I am trying to simplify data binding by calling a function like
BindToText(titleTextBox, ()=>foo.Title );
该声明像
which is declared like
void BindToText<T>(Control control, Expression<Func<T>> property)
{
var mex = property.Body as MemberExpression;
string name = mex.Member.Name;
control.DataBindings.Add("Text", ??? , name);
}
让我怎么放在 ???
我的富
类的实例。我如何获得refernce给调用从lambda表达式富
实例
so what do I put in ???
for the instance of my Foo
class. How do I get a refernce to the calling foo
instance from the lambda expression?
编辑:<? / STRONG>
上的实例应该存在的地方,因为我可以叫 property.Compile()
,并创建一个使用富<委托/ code>例如我的
BindToText
函数内。所以我的问题是,如果这样可以不会在功能参数,增加了实例的引用来完成。我呼吁 Occum剃刀来产生简单的解决方案。
edit:
The instance should be there somewhere because I can call property.Compile()
and create a delegate that uses the foo
instance inside my BindToText
function. So my question is if this can be done without adding a reference to the instance in the function parameters. I call upon Occum's Razor to yield the simplest solution.
编辑2:
众多什么都没有注意到的是关闭的存在于访问的实例富
我的函数里,如果我编译的lambda。编译器怎么会知道哪里可以找到实例,我不?我坚持认为,必须有一个答案,的没有的有传递一个额外的参数。
edit 2:
What many have failed to notice is the closure that exists in accessing the instance of foo
inside my function, if I compile the lambda. How come the compiler knows where to find the instance, and I don't? I insist that there has to be an answer, without having to pass an extra argument.
感谢 VirtualBlackFox 解决方案是这样的:
Thanks to VirtualBlackFox the solution is such:
void BindText<T>(TextBoxBase text, Expression<Func<T>> property)
{
var mex = property.Body as MemberExpression;
string name = mex.Member.Name;
var fex = mex.Expression as MemberExpression;
var cex = fex.Expression as ConstantExpression;
var fld = fex.Member as FieldInfo;
var x = fld.GetValue(cex.Value);
text.DataBindings.Add("Text", x, name);
}
这alows我只需键入 BindText(titleText, ()=> foo.Title);
推荐答案
void Foo<T>(Expression<Func<T>> prop)
{
var propertyGetExpression = prop.Body as MemberExpression;
// Display the property you are accessing, here "Height"
propertyGetExpression.Member.Name.Dump();
// "s" is replaced by a field access on a compiler-generated class from the closure
var fieldOnClosureExpression = propertyGetExpression.Expression as MemberExpression;
// Find the compiler-generated class
var closureClassExpression = fieldOnClosureExpression.Expression as ConstantExpression;
var closureClassInstance = closureClassExpression.Value;
// Find the field value, in this case it's a reference to the "s" variable
var closureFieldInfo = fieldOnClosureExpression.Member as FieldInfo;
var closureFieldValue = closureFieldInfo.GetValue(closureClassInstance);
closureFieldValue.Dump();
// We know that the Expression is a property access so we get the PropertyInfo instance
// And even access the value (yes compiling the expression would have been simpler :D)
var propertyInfo = propertyGetExpression.Member as PropertyInfo;
var propertyValue = propertyInfo.GetValue(closureFieldValue, null);
propertyValue.Dump();
}
void Main()
{
string s = "Hello world";
Foo(() => s.Length);
}
这篇关于我怎样才能对象实例从()=> foo.Title表达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!