gpt4 book ai didi

c# - 如何从 ()=>foo.Title 表达式中获取对象实例

转载 作者:IT王子 更新时间:2023-10-29 04:19:27 25 4
gpt4 key购买 nike

我有一个带有属性的简单类

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com