我有以下两个班级。地址包含地址列表。方法GetMailingAddress将扫描AddressList以查找特定类型的地址。
Class Addresses
{
public List<Address> AddressList {get; set;}
public Address MailingAddress {get { return GetMailingAddress();}
}
Class Address
{
public Int? ID {get; set;}
}
要访问MailingAddress的ID,我将输入以下内容:
Addresses obj = new Addresses();
int? I = obj.MailingAddress.ID
问题是MailingAddress可以返回null。如果发生这种情况,则调用失败,因为它通过null对象引用ID。在这种情况下,我想返回null。
要解决此问题,请使用以下代码:
if(obj.MailingAddress == null)
{
I? = null;
}
else
{
I? = obj.MailingAddress.ID;
}
有没有办法调用obj.MailingAddress.ID并且如果MailingAddress为null则返回null,而不必执行上述If语句。
我还可以像这样在类地址中创建一个额外的方法/属性,但我再次将其视为一种解决方法,而不是一个干净的解决方案:
public int? MailingAddressID
{
if(GetMailingAddress == null)
{
return null;
}
else
{
return GetMailingAddress.ID;
}
}
答案 0 :(得分:2)
首先int
是结构,你必须使用?
或Nullable<int>
使其可以为空,然后:
int? myInt = obj.MailingAddress == null ? (int?)null : (int?)obj.MailingAddress.Id;
但是,在C#6中,您可以使用?
运算符,有时也称为 Safe Navigation Operator :
int? myInt = obj?.MailingAddress?.Id;
作为补充说明,您可以使用Null Object Pattern。您可以从here了解它并使用此模式。 Null Object
模式的使用简化了代码,使其不易出错。
答案 1 :(得分:0)
这是C#5中C#6 Null Propagation语法的愚蠢实现:
using System;
using System.Diagnostics;
public class Program
{
public static void Main()
{
var foo = new Foo { Bar = new Bar { Baz = "Hello" } };
var foo1 = new Foo();
var i = foo._(_=>_.Bar)._(_=>_.Baz); //equivalent to foo?.Bar?.Baz in C# 6
Console.WriteLine("i is '{0}'", i); //should be 'Hello'
var j = foo1._(_=>_.Bar)._(_=>_.Baz); //equivalent to foo1?.Bar?.Baz in C# 6
Console.WriteLine("j is '{0}'",j); //should be '' since j is null, but shouldn't throw exception either.
Console.WriteLine("js is null? {0}", j == null);
}
}
public class Foo
{
public Bar Bar { get; set; }
}
public class Bar
{
public string Baz { get; set; }
}
public static class ObjectExtension
{
//Probably not a good idea to name your method _, but it's the shortest one I can find, I wish it could be _?, but can't :(
public static K _<T, K>(this T o, Func<T, K> f)
{
try
{
var z = f(o);
return z;
}
catch(NullReferenceException nex)
{
Trace.TraceError(nex.ToString());
return default(K);
}
}
}
基本上我想做foo?.Bar?.Baz
,但由于语法不受支持,扩展方法Func<..>
和救援的通用......
这样您就不需要将对象更改为可空版本,但需要在调用扩展方法_
中指定其类型。 foo._(_=>_.Bar)._(_=>_.Baz)
看起来有点奇怪,但相当简洁:)