调用了错误的方法

时间:2015-04-21 10:11:46

标签: c#

以下代码在功能上可能看起来很奇怪。这是因为这是对更大的东西的简化表示。

我有一个class名为,此人有一个property名为字符串名称

在名为 ClassRoom 的另一个class中,我有以下constructors

protected ClassRoom() { }

public ClassRoom(Person person) : this(person == null ? null : person, person.Name) { }

public ClassRoom(Person person, string name)
{
    // Possible NullReferenceException which is not that important because it can be anticipated on.
    person.Name = name;
}

ClassRoom(Person person)的目标是,如果为空,则会调用ClassRoom(),如果它不为空,则会调用ClassRoom(Person person, string name)

为确保此功能正常,我编写了单元测试。当我在测试中new ClassRoom(null)时,ClassRoom(Person person, string name)中会抛出 NullReferenceException ,这让我感到惊讶。如果ClassRoom(Person person)中的为空,则不应该调用ClassRoom()而不是ClassRoom(Person person, string name)

2 个答案:

答案 0 :(得分:4)

  

我对ClassRoom(Person person)的目标是,如果Person为null,则调用ClassRoom(),如果它不为null,则调用ClassRoom(Person person,string name)。

基本上你不能这样做。您无法决定在执行时链接到哪个构造函数。重载分辨率在编译时执行,这就决定了你要链接到的内容。目前尚不清楚为什么你希望你当前的代码能够做到这一点,但你完全不能这样做。

基本上你应该重新考虑你的设计。通常,对于具有较少参数的构造函数来说,调用具有更多参数的构造函数,传递默认值是个好主意。例如:

protected ClassRoom() : this(null)
{
}

public ClassRoom(Person person)
    : this(person, person == null ? "" : person.Name)
{
}

public ClassRoom(Person person, string name)
{
    this.person = person;
    this.name = name;
}

答案 1 :(得分:0)

如果这里的目的是提供这种空检查功能,而不必在每次创建ClassRoom时都进行这样的检查,那么您可以尝试使用以下模式:

public class ClassRoom
{
    public static ClassRoom CreateClassRoom(Person person = null)
    {
        if(person == null)
            return new ClassRoom();
        else 
            return new ClassRoom(person,person.Name);
    }

    private ClassRoom()
    {
    }
    private ClassRoom(Person person, string name)
    {
        //Not sure why you would do this, because you're setting it to what it already is.
        person.Name = name;
    }
}

然后,要创建一个ClassRoom,请执行以下操作:

var classRoom1 = ClassRoom.CreateClassRoom(new Person());
var classRoom2 = ClassRoom.CreateClassRoom(null);
var classRoom3 = ClassRoom.CreateClassRoom();