ja7*_*a72 26 c# data-binding lambda expression-trees .net-3.5
我有一个带有属性的简单类
class Foo
{
string Title { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我试图通过调用函数来简化数据绑定
BindToText(titleTextBox, ()=>foo.Title );
Run Code Online (Sandbox Code Playgroud)
这被宣称为
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);
}
Run Code Online (Sandbox Code Playgroud)
那么我应该???为我的Foo班级实例投入什么呢.如何foo从lambda表达式中获取对调用实例的引用?
编辑:
实例应该在某处,因为我可以调用property.Compile()并创建一个使用foo我的BindToText函数中的实例的委托.所以我的问题是,如果可以在不添加函数参数中实例的引用的情况下完成此操作.我呼吁Occum的Razor提供最简单的解决方案.
编辑2:
许多人没有注意到的是在我的函数内部访问实例时存在的闭包foo,如果我编译lambda.为什么编译器知道在哪里找到实例,我不知道?我坚持认为必须有一个答案,而不必通过额外的论证.
感谢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);
}
Run Code Online (Sandbox Code Playgroud)
这让我只需输入BindText(titleText, () => foo.Title);.
Jul*_*lia 16
您想要的小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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5820 次 |
| 最近记录: |