假设,我有这个界面,
interface IContact
{
IAddress address { get; set; }
}
interface IAddress
{
string city { get; set; }
}
class Person : IPerson
{
public IContact contact { get; set; }
}
class test
{
private test()
{
var person = new Person();
if (person.contact.address.city != null)
{
//this will never work if contact is itself null?
}
}
}
Run Code Online (Sandbox Code Playgroud)
Person.Contact.Address.City != null (这可以检查City是否为空.)
但是,如果Address或Contact或Person本身为null,则此检查将失败.
目前,我能想到的一个解决方案是:
if (Person != null && Person.Contact!=null && Person.Contact.Address!= null && Person.Contact.Address.City != …Run Code Online (Sandbox Code Playgroud) 假设我有一个表达式,它只是一个成员访问运算符链:
Expression<Func<Tx, Tbaz>> e = x => x.foo.bar.baz;
Run Code Online (Sandbox Code Playgroud)
您可以将此表达式视为子表达式的组合,每个子表达式包含一个成员访问操作:
Expression<Func<Tx, Tfoo>> e1 = (Tx x) => x.foo;
Expression<Func<Tfoo, Tbar>> e2 = (Tfoo foo) => foo.bar;
Expression<Func<Tbar, Tbaz>> e3 = (Tbar bar) => bar.baz;
Run Code Online (Sandbox Code Playgroud)
我想要做的是分解e成这些组件子表达式,以便我可以单独使用它们.
如果我有表达x => x.foo.bar,我已经知道如何中断x => x.foo.如何拉出其他子表达式foo => foo.bar?
我试图在C#中模拟"提升"成员访问操作符,就像CoffeeScript的存在访问操作符一样?..Eric Lippert表示,类似的运营商被考虑用于C#,但没有预算来实施它.
如果这样的运算符存在于C#中,您可以执行以下操作:
value = target?.foo?.bar?.baz;
Run Code Online (Sandbox Code Playgroud)
如果target.foo.bar.baz链的任何部分结果为null,那么整个事情将评估为null,从而避免NullReferenceException.
我想要一个Lift可以模拟这种事情的扩展方法:
value = target.Lift(x => x.foo.bar.baz); //returns target.foo.bar.baz or null
Run Code Online (Sandbox Code Playgroud)
可能重复:
C#中的安全导航操作员?
"如果object为null,则为null;如果object为null,则为object.member"的快捷方式
在我的XML处理项目中,我必须浏览链式属性以获得所需的值.例如,obj1.obj2.obj3.obj4.obj....Value.并且可能退出此链中的任何对象为null.
我用Google搜索了"c#中的NullSafe导航"并找到了一些不错的文章.从Post之一,我有了实现自定义扩展的想法.现在我对这个扩展的性能有疑问.我有这3个解决方案.任何人都可以建议我采用哪一种(在性能方面)?
选项1(使用本文中解释的逻辑):
//custom extension method
public static TOutput IfNotNull<TInput, TOutput>(this TInput x, Func<TInput, TOutput> f)
where TInput : class
where TOutput : class
{
return x == null ? null : f(x);
}
//with custom extension method -- Very neat & clean.. but what about performance?
string x = obj1
.IfNotNull(x => x.obj2)
.IfNotNull(x => x.obj3)
.IfNotNull(x => x.obj4)
.IfNotNull(x => x.obj5)
.IfNotNull(x => x.Value);
Run Code Online (Sandbox Code Playgroud)选项2:
//with NullCheck -- probably …Run Code Online (Sandbox Code Playgroud)