【发布时间】:2025-12-21 02:30:11
【问题描述】:
假设我定义了这些虚拟类:
public class MyObject
{
public InterestingFact InterestingFact { get; set; }
}
public class InterestingFact
{
public Detail Detail { get; set; }
}
public class Detail
{
public string Information { get; set; }
}
我还有一个MyObject的实例:
var obj = new MyObject() { InterestingFact = new InterestingFact() };
如果我想尝试访问 Information 属性,我可以这样做:
string info = null;
if (obj != null
&& obj.InterestingFact != null
&& obj.InterestingFact.Detail != null)
{
info = obj.InterestingFact.Detail.Information;
}
为了讨论,忽略得墨忒耳法则,每次我想访问我拥有的对象深处的东西时,这并不是一件很有趣的事情。当然,我可以创建一个扩展方法:
public static U NullOr<T, U>(this T target, Func<T, U> selector)
{
if (EqualityComparer<T>.Default.Equals(target, default(T)))
{
return default(U);
}
return selector(target);
}
这使得选择数据更容易一些:
// Here I have a null of type string.
var info = obj.NullOr(o => o.InterestingFact).NullOr(f => f.Detail).NullOr(d => d.Information);
但是,这仍然有点啰嗦。理想情况下,我想做更多这样的事情:
// Here I should still have a null of type string.
var info = obj.NullOr(o => o.InterestingFact.Detail.Information);
我从未与Expressions 合作过;如果我使用Expression<Func<T, U>> 而不是NullOr 中的Func<T, U>,在我看来它是一个成员访问权限而不是三个成员访问权限。有没有办法解决上述问题,还是这个公式遥不可及?
(当然,还有人担心最后一个公式,发送的表达式可能不仅仅是链式成员访问..)
【问题讨论】:
-
这是 proposed 使用
?.运算符对 C# 的补充,但它还没有进入语言。 Mads 说他们正在认真考虑,所以有一天你可以写信obj?.InterestingFact?.Detail?.Information。在那之前,你做的方式是我知道的唯一方式。 -
@MosheKatz:我已经看到了,我希望我可以通过运算符重载来实现。
-
@MosheKatz:谢谢!我不知道我是怎么错过的。