2016-09-19 108 views
2

我爲了更好地解釋我的情況由一個例子重載構造函數時如何避免NullReferenceException?

void Main() 
{ 
    var a = new Lol(null); 
} 

public class Lol 
{ 
    public Lol(string a, string b) 
    { 
     if(a == null || b == null) 
     { 
      throw new Exception(); 
     } 
    } 

    public Lol(Tuple<string, string> k) 
     : this(k.Item1, k.Item2) 
    { 
    } 
} 

在這種情況下,我在第二個構造得到一個NullReferenceException。有沒有辦法從方法內部處理它,保持相同的結構,或者我應該創建一個私有方法,並有兩個構造函數稱爲此方法?

+2

如果你有C#6(VS 2015),你可以執行'this(k?.Item1,k?.Item2)'。 – juharr

+3

或者不要調用'this ...'並在第二個構造函數內部執行,這可能更合適,因爲您在那裏執行不同的空值檢查。 – DavidG

+0

不要這樣稱呼。在實際的第二個構造函數中處理任何賦值。然後,你可以在構造函數裏面進行空檢查。 – Jay

回答

1

可以抽象邏輯到一個輔助方法,並有兩個構造叫幫手。

public class Lol 
{ 
    public Lol(string a, string b) 
    { 
     LolHelper(a, b); 
    } 

    public Lol(Tuple<string, string> k) 
    { 
     (k!=null) 
      ?LolHelper(k.Item1, k.Item2) 
      :LolHelper(null, null); 
    } 

    private void LolHelper(string a, string b) 
    { 
     if(a == null || b == null) 
     { 
      throw new Exception(); 
     } 
    } 
} 
0

這是由設計,你需要做一次檢查在第二個構造

public Lol(Tuple<string, string> k) 

{ 
    if(k == null || k.Item1 == null || k.Item2 == null) 
    { 
     throw new Exception(); 
    } 
} 
+0

如何從中調用其他構造函數? – Phate01

+0

你不知道。在每個類中設置類的字段,並使用通用的初始化函數完成其餘部分。 –

1

不改變任何邏輯,你可以這樣做:

public class Lol 
{ 
    public Lol(string a, string b) 
    { 
     if(a == null || b == null) 
     { 
      throw new Exception(); 
     } 
    } 

    public Lol(Tuple<string, string> k) 
    : this(k != null ? k.Item1 : null, k != null ? k.Item2 : null) 
    { 
    } 
} 

然而,在更復雜的情況下,這可能無法正常工作(雖然你不應該把任何複雜的邏輯構造反正鏈接)。

1

這應該與VS2015的工作與C#6:

this(k?.Item1, k?.Item2) 

最後:

void Main() 
{ 
    var a = new Lol(null); 
} 

public class Lol 
{ 
    public Lol(string a, string b) 
    { 
     if(a == null || b == null) 
      throw new Exception(); 
    } 

    public Lol(Tuple<string, string> k) 
     : this(k?.Item1, k?.Item2) 
    { 
    } 
} 
+0

其實這並不依賴於.Net版本,而是編譯器的版本,特別是C#6,它是VS 2015的一部分。 – juharr

+0

感謝您的澄清,我將編輯我的答案,然後:) –

1

如果不傳遞null在構造函數中位居第一。如果你希望你的字段或對應於性能和b爲null只是把它的構造是這樣的:

private string a; 
private string b; 
public Lol() 
     { 
      a= null; 
      b= null; 
     } 

在Main()使用方法:

var a = new Lol(); 

,如果你想傳遞值,不爲null,使用適當的構造函數。

+0

我必須檢查Tuple不要爲零,我也不需要無參數的構造函數 – Phate01

+0

@ Phate01。你的意思是檢查這個元組是否在事前被初始化。有沒有你不會初始化的腳本。如果沒有,那麼你不需要檢查它爲空。在另一種情況下,我爲誤解你而道歉。順便說一下,最好在物業內進行檢查。 –