作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个带有属性的简单类
class Foo
{
string Title { get; set; }
}
我正在尝试通过调用像这样的函数来简化数据绑定(bind)
BindToText(titleTextBox, ()=>foo.Title );
声明如下
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);
}
那么我要在 ???
中为我的 Foo
类的实例放入什么。如何从 lambda 表达式中获取对调用 foo
实例的引用?
编辑:该实例应该存在于某处,因为我可以调用 property.Compile()
并在我的 BindToText
函数中创建一个使用 foo
实例的委托(delegate)。所以我的问题是,如果不在函数参数中添加对实例的引用,是否可以做到这一点。我呼吁Occum's Razor产生最简单的解决方案。
编辑 2:许多人没有注意到的是,如果我编译 lambda,在我的函数中访问 foo
实例时存在的闭包。为什么编译器知道在哪里可以找到实例,而我却不知道?我坚持认为必须有一个答案,而不必传递额外的参数。
感谢VirtualBlackFox解决方案是这样的:
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);
}
这让我只需输入 BindText(titleText, () => foo.Title);
。
最佳答案
小 LINQPad你想要的样本:
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);
}
关于c# - 如何从 ()=>foo.Title 表达式中获取对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5092387/
我是一名优秀的程序员,十分优秀!