2016-09-19 106 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。你的意思是检查这个元组是否在事前被初始化。有没有你不会初始化的脚本。如果没有,那么你不需要检查它为空。在另一种情况下,我为误解你而道歉。顺便说一下,最好在物业内进行检查。 –