【发布时间】:2016-01-07 01:06:37
【问题描述】:
使用 C# 6,我们可以使用新的 ? 来访问属性和方法,而无需检查每个属性和方法是否为空。是否可以使用表达式编写具有类似功能的方法?
例如,我必须使用奇怪的对象结构(来自我们无法更改的第 3 方库)。访问某些属性通常需要很长的点链:
rootObject.Services.First().Segments.First().AnotherCollection.First().Weight;
rootObject 之后的任何对象都可以是null。我宁愿不要在它周围加上try/catch。单独检查每个属性也是很多工作。所以我想知道是否可以将它传递给采用表达式并遍历每个属性并在那里检查其值的方法:
var value = PropertyHelper.GetValue(() => rootObject.Services.First().Segments.First().AnotherCollection.First().Weight);
我猜它的签名应该是这样的:
public static T GetValue<T>(Expression<Func<T>> expression)
{
// analyze the expression and evaluate each property/method
// stop when null or return the value
}
我不确定表达式是否能够完成我将要做的事情,在我开始实验之前,我想问问它是否可能。
【问题讨论】:
-
他们将其添加为运算符是有原因的。这是可能的,但它比C# 6 运算符使用起来要笨重得多。在处理 C# 运算符能够解决的不可为空的类型方面也存在一些问题(而且您永远无法解决)。
-
好吧,你可以创建(子类化)一个
ExpressionVisitor来检查成员访问、调用等,并注入(到重写的表达式中)检查,但是......这是很多反思和很多访问,然后你要么需要Compile()它(添加元编程)或添加甚至更多反射以在运行时评估树......似乎有很多开销跨度> -
@MarcGravell 是的,尽管如果有问题的代码不在应用程序对性能特别敏感的部分,或者不经常调用,或者编译的委托可以重用,那么性能可能不会糟糕到可以排除解决方案。
-
@Servy 我认为另一个问题也差不多回答了我的问题,而且我不知道如何以不同的方式表述它,这就是我可能没有找到它的原因。我会研究它并尝试一些东西。谢谢。
-
@MarcGravell 如果可行,那我就开始工作 ;-) 我用另一个问题来寻找灵感。
标签: c# reflection lambda