C#6更新
// C#1-5
propertyValue1 = myObject != null ? myObject.StringProperty : null;
// C#6
propertyValue1 = myObject?.StringProperty;
Run Code Online (Sandbox Code Playgroud)
下面的问题仍适用于旧版本,但如果使用new ?.运算符开发新应用程序则更好.
原始问题:
我经常想要访问可能为null的对象的属性:
string propertyValue1 = null;
if( myObject1 != null )
propertyValue1 = myObject1.StringProperty;
int propertyValue2 = 0;
if( myObject2 != null )
propertyValue2 = myObject2.IntProperty;
Run Code Online (Sandbox Code Playgroud)
等等...
我经常使用它,因此我有一个代码片段.
如果符合以下条件,您可以在某种程度上缩短此内容:
propertyValue1 = myObject != null ? myObject.StringProperty : null;
Run Code Online (Sandbox Code Playgroud)
然而,这有点笨拙,特别是如果设置大量属性或多个级别可以为null,例如:
propertyValue1 = myObject != null ?
(myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null : null;
Run Code Online (Sandbox Code Playgroud)
我真正想要的是 …
如何在深层lamda表达式中检查空值?
比方说,我有一个嵌套了几层深度的类结构,我想执行以下lambda:
x => x.Two.Three.Four.Foo
Run Code Online (Sandbox Code Playgroud)
如果Two,Three或Four为null,我希望它返回null,而不是抛出System.NullReferenceException.
public class Tests
{
// This test will succeed
[Fact]
public void ReturnsValueWhenClass2NotNull()
{
var one = new One();
one.Two = new Two();
one.Two.Three = new Three();
one.Two.Three.Four = new Four();
one.Two.Three.Four.Foo = "blah";
var result = GetValue(one, x => x.Two.Three.Four.Foo);
Assert.Equal("blah", result);
}
// This test will fail
[Fact]
public void ReturnsNullWhenClass2IsNull()
{
var one = new One();
var result = GetValue(one, x => x.Two.Three.Four.Foo);
Assert.Equal(null, result);
}
private TResult GetValue<TModel, TResult>(TModel model, …Run Code Online (Sandbox Code Playgroud) 我有一个MVC剃刀视图迭代Orders集合.每个订单都有一个Customer,可以为null.
麻烦的是,在这种情况下,我得到一个空引用异常.
@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
<td>
@item.Number
</td>
<td>
@String.Format("{0:g}", item.ReceivedDate)
</td>
<td>
@item.Customer.Name
</td>
Run Code Online (Sandbox Code Playgroud)
当item.Customer为null(正如您所期望的那样)时,@ item.Customer.Name会爆炸.
这一定是一个简单的问题,但一直无法找到答案!
在没有设置ViewModel的情况下,处理此问题的最佳方法是什么?
谢谢邓肯
可能重复:
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)是否有一个非 空的合并运算符,在C#这种情况下可以使用如下:
public void Foo(string arg1)
{
Bar b = arg1 !?? Bar.Parse(arg1);
}
Run Code Online (Sandbox Code Playgroud)
以下案例让我想到了:
public void SomeMethod(string strStartDate)
{
DateTime? dtStartDate = strStartDate !?? DateTime.ParseExact(strStartDate, "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
}
Run Code Online (Sandbox Code Playgroud)
我可能没有strStartDate信息,以防万一,null但如果我这样做; 我总是确定它将是预期的格式.因此,而不是初始化dtStartDate = null并尝试parse在try catch块内设置值.它似乎更有用.
我想答案是否定的(并且没有这样的运算符!??或其他任何东西)我想知道是否有一种方法可以实现这种逻辑,它是否值得以及它会变得有用的情况.