gpt4 book ai didi

c# - 从属性表达式中获取属性的拥有对象

转载 作者:太空狗 更新时间:2023-10-29 23:24:34 25 4
gpt4 key购买 nike

我正在编写一些代码,其最终目的是让您使用属性表达式来设置属性的值,其语法类似于将变量作为 out 或 ref 参数传递。

类似的东西:

public static foo(()=>Object.property, value);

并且Object.Property会被赋值为value。

我正在使用以下代码获取属性的欠对象:

public static object GetOwningObject<T>(this Expression<Func<T>> @this)
{
var memberExpression = @this.Body as MemberExpression;
if (memberExpression != null)
{
var fieldExpression = memberExpression.Expression as MemberExpression;
if (fieldExpression != null)
{
var constExpression = fieldExpression.Expression as ConstantExpression;
var field = fieldExpression.Member as FieldInfo;
if (constExpression != null) if (field != null) return field.GetValue(constExpression.Value);
}
}
return null;
}

因此,当用在像 ()=>Object.Property 这样的属性表达式上时,这将返回“Object”的实例。我对使用属性表达式有些陌生,似乎有很多不同的方法来完成事情,但我想扩展我目前所拥有的,以便给定一个表达式,例如 ()=>Foo.Bar.Baz 它会给出 Bar,而不是 Foo。我总是想要表达式中的最后一个包含对象。

有什么想法吗?提前致谢。

最佳答案

你要做的就是遍历属性链到最外层的对象。下面的示例不言自明,表明扩展方法适用于链式字段和属性:

class Foo
{
public Bar Bar { get; set; }
}

class Bar
{
public string Baz { get; set; }
}

class FooWithField
{
public BarWithField BarField;
}

class BarWithField
{
public string BazField;
}

public static class LambdaExtensions
{
public static object GetRootObject<T>(this Expression<Func<T>> expression)
{
var propertyAccessExpression = expression.Body as MemberExpression;
if (propertyAccessExpression == null)
return null;

//go up through property/field chain
while (propertyAccessExpression.Expression is MemberExpression)
propertyAccessExpression = (MemberExpression)propertyAccessExpression.Expression;

//the last expression suppose to be a constant expression referring to captured variable ...
var rootObjectConstantExpression = propertyAccessExpression.Expression as ConstantExpression;
if (rootObjectConstantExpression == null)
return null;

//... which is stored in a field of generated class that holds all captured variables.
var fieldInfo = propertyAccessExpression.Member as FieldInfo;
if (fieldInfo != null)
return fieldInfo.GetValue(rootObjectConstantExpression.Value);

return null;
}
}

[TestFixture]
public class Program
{
[Test]
public void Should_find_root_element_by_property_chain()
{
var foo = new Foo { Bar = new Bar { Baz = "text" } };
Expression<Func<string>> expression = () => foo.Bar.Baz;
Assert.That(expression.GetRootObject(), Is.SameAs(foo));
}

[Test]
public void Should_find_root_element_by_field_chain()
{
var foo = new FooWithField { BarField = new BarWithField { BazField = "text" } };
Expression<Func<string>> expression = () => foo.BarField.BazField;
Assert.That(expression.GetRootObject(), Is.SameAs(foo));
}
}

关于c# - 从属性表达式中获取属性的拥有对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13748880/

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