具有相同参数类型的构造函数

时间:2008-08-27 20:39:52

标签: c# .net oop

我有一个带有两个构造函数的Person对象 - 一个接受一个int(personId),另一个接受一个字符串(logonName)。我想要另一个带字符串的构造函数(badgeNumber)。我知道这不可能做到,但似乎这可能是一种常见的情况。有一种优雅的方式处理这个?我想这适用于任何重载方法。代码:

public class Person
{
    public Person() {}

    public Person(int personId)
    {
        this.Load(personId);
    }

    public Person(string logonName)
    {
        this.Load(logonName);
    }

    public Person(string badgeNumber)
    {
        //load logic here...
    }

...等

13 个答案:

答案 0 :(得分:18)

你可以改用工厂方法吗?

public static Person fromId(int id) {
    Person p = new Person();
    p.Load(id);
    return p;
}
public static Person fromLogonName(string logonName) {
    Person p = new Person();
    p.Load(logonName);
    return p;
}
public static Person fromBadgeNumber(string badgeNumber) {
    Person p = new Person();
    // load logic
    return p;
}
private Person() {}

答案 1 :(得分:7)

您可以考虑使用自定义类型。

例如,创建LogonName和BadgeNumber类。

然后你的函数声明看起来像......

public Person(LogonName ln)
{
    this.Load(ln.ToString());
}

public Person(BadgeNumber bn)
{
    //load logic here...
}

这样的解决方案可能会为您提供一个保持管理这些字符串的格式和用法的业务逻辑的好地方。

答案 2 :(得分:2)

您可以考虑四个选项,其中三个已经被其他人命名:

  1. 按照其他几个人的建议走工厂路线。这样做的一个缺点是你不能通过重载进行一致的命名(否则你会遇到同样的问题),所以它表面上看不太干净。另一个更大的缺点是它排除了直接在堆栈上分配的可能性。如果采用这种方法,一切都将在堆上分配。

  2. 自定义对象包装器。这是一个很好的方法,如果你是从头开始我会推荐的方法。如果你有很多代码使用,例如徽章作为字符串,那么重写代码可能会使这成为一个不可行的选择。

  3. 向方法添加枚举,指定如何处理字符串。这有效,但要求您重写所有现有调用以包含新枚举(尽管如果需要可以提供默认值以避免其中一些)。

  4. 添加一个未用于区分两个重载的虚拟参数。例如在方法上添加bool。这种方法由标准库在一些地方采用,例如std::nothrowoperator new的虚拟参数。这种方法的缺点是丑陋而且不能扩展。

  5. 如果您已有大量现有代码,我建议您添加枚举(可能使用默认值)或添加虚拟参数。两者都不漂亮,但两者都很容易改造。

    如果您是从头开始,或者只有少量代码,我建议使用自定义对象包装器。

    如果你的代码大量使用原始的badge / logonName字符串,但是没有大量使用Person类,那么工厂方法就是一个选项。

答案 3 :(得分:2)

如果您使用的是C#3.0,则可以使用Object Initializers

public Person()
{
}

public string Logon { get; set; }
public string Badge { get; set; }

你可以像这样调用构造函数:

var p1 = new Person { Logon = "Steve" };
var p2 = new Person { Badge = "123" };

答案 4 :(得分:1)

没有

你可以考虑一个标志字段(enum的可读性),然后让构造函数使用htat来确定你的意思。

答案 5 :(得分:1)

那不行。您可以考虑创建一个名为BadgeNumber的类来包装字符串,以避免这种歧义。

答案 6 :(得分:1)

您不能拥有两个具有相同签名的不同构造函数/方法,否则,编译器如何确定要运行的方法。

作为Zack said,我会考虑创建一个“选项”类,您可以在其中实际传递自定义类型中包含的参数。这意味着您可以随意传递尽可能多的参数,并使用选项执行您喜欢的操作,请注意不要创建一个尝试执行所有操作的单片方法。

要么是,要么投票给factory pattern ..

答案 7 :(得分:1)

您可以使用静态工厂方法:

public static Person fromLogon(String logon) { return new Person(logon, null); }
public static Person fromBadge(String badge) { return new Person(null, badge); }

答案 8 :(得分:1)

正如所建议的那样,自定义类型是这种情况下的方法。

答案 9 :(得分:0)

我只能想到处理你想要做的事情就是必须使用params,一个描述param类型(一个带有LogonName,BadgeNumer等的枚举),第二个是param值。

答案 10 :(得分:0)

您可以切换到工厂样式。

public class Person {

  private Person() {}

  public static PersonFromID(int personId)
  {
    Person p = new Person().
    person.Load(personID);

    return p;
    this.Load(personId);
  }

  public static PersonFromID(string name)
  {
    Person p = new Person().
    person.LoadFromName(name);

    return p;
  }

  ...
}

或者,如建议的那样,使用自定义类型。您也可以使用泛型来破解某些东西,但我不建议将其用于可读性。

答案 11 :(得分:0)

取决于您的业务限制:

public class Person
{
    public string Logon { get; set; } = "";
    public string Badge { get; set; } = "";
    
    public Person(string logon="", string badge="") {}
}
// Use as follow 
Person p1 = new Person(logon:"MylogonName");
Person p2 = new Person(badge:"MyBadge");

答案 12 :(得分:-2)

怎么样......

public Person(int personId)
{
    this.Load(personId);
}

public Person(string logonName)
{
    this.Load(logonName);
}

public Person(Object badgeNumber)
{
    //load logic here...
}