2015-05-14 73 views
2

我有以下兩個類。地址包含地址列表。方法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。如果發生這種情況,調用將失敗,因爲它通過空對象引用ID。在這個例子中,我想返回null。

要解決此我使用此代碼:

if(obj.MailingAddress == null) 
{ 
    I? = null; 
} 
else 
{ 
    I? = obj.MailingAddress.ID; 
} 

有沒有一種方法來調用obj.MailingAddress.ID而無需做上面的if語句返回null MailingAddress爲null。

我還可以創建類地址這樣內的附加方法/屬性,但我又認爲這是一個解決辦法,而不是一個乾淨的解決方案:

public int? MailingAddressID 
{ 
    if(GetMailingAddress == null) 
    { 
     return null; 
    } 
    else 
    { 
     return GetMailingAddress.ID; 
    } 
} 
+0

你一定會喜歡C#6,然後......你可以做'變種I = OBJ .MailingAddress .ID;'和你會得到你想要的價值。請參閱:https://dotnetfiddle.net/THfoBi –

回答

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模式可以簡化代碼並使其不易出錯。

+0

是的。對我來說這是一種過度的視線。 –

+0

很好的回答。我試圖做到這一點,但只是不能得到它的工作。不能等到C#6. obj?.obj?.id是非常好的。 –

+0

@SimonDarlow很高興幫助。祝你好運。 –

0

這裏是一個愚蠢的實現C#6空傳播語法的C#5:

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)看起來有點怪異,但很簡潔:)

在現場樣本:??https://dotnetfiddle.net/9R8bku

+0

對我來說太瘋狂了。我的C#知識不能應付:) –

+0

我說過這是一個瘋狂的方式,大聲笑 –