2016-09-19 6 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) 
    { 
    } 
} 

はこの場合、私は2番目のコンストラクタでNullReferenceExceptionを取得していますより良い説明するために例を作りました。同じ構造体を保持しているメソッドの中からメソッドを処理する方法はありますか?またはプライベートメソッドを作成し、両方のコンストラクターにこのメソッドを呼び出させる必要がありますか?これは仕様によるものです

+2

C#6(VS 2015)をお持ちの場合は、 'this(k?.Item1、k?.Item2)'を実行できます。 – juharr

+3

また、 'this ... 'を呼び出さずに2番目のコンストラクタの中で実行してください。これは、別のヌルチェックを行っているので、より適切かもしれません。 – DavidG

+0

これを呼び出さないでください。実際の2番目のコンストラクタの割り当てを処理します。次に、コンストラクタ自体の中でヌルチェックを行うことができます。 – 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

これは、C#6でVS2015で動作します:

最後に
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バージョンに依存しませんが、特にVS 2015の一部であるC#6のコンパイラのバージョンです。 – juharr

+0

明確化のおかげで、私は私の答えを編集します:) –

1

最初の場所で、コンストラクタにnullを渡していないことで。あなたのフィールドまたはプロパティをしたい場合は、単に次のようにコンストラクタでそれを置くNULLにaとbに対応する:メイン(中

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

)を使用します。

var a = new Lol(); 

あなたがしたい場合はnullでない値を渡して、適切なコンストラクタを使用します。

+0

タプルをチェックする必要がありますnullでもないので、パラメータのないコンストラクタは必要ありません。 – Phate01

+0

@ Phate01。タプルが事前に初期化されているかどうかをチェックすることを意味します。あなたがそれを初期化しないスクリプトがありますか?そうでない場合は、nullをチェックする必要はありません。それ以外の場合、私はあなたを誤解して謝罪します。ちなみに、プロパティ内で小切手をする方がいいです。 –

関連する問題