具有相同参数签名的C#构造函数

时间:2009-01-28 15:36:31

标签: c# .net

我确信这一定是个常见问题。我有一个课程,在理想世界中会有以下构造函数

public Thing(string connectionString)

public Thing(string fileName)

显然这是不允许的,因为签名是相同的。有人知道这个问题的优雅解决方案吗?

7 个答案:

答案 0 :(得分:41)

您可以使用命名的构造函数idiom:

public class Thing
{
    private string connectionString;

    private string filename;

    private Thing()
    {
        /* Make this private to clear things up */
    }

    public static Thing WithConnection(string connectionString)
    {
        var thing = new Thing();
        thing.connectionString = connectionString;
        return thing;
    }

    public static Thing WithFilename(string filename)
    {
        var thing = new Thing();
        thing.filename = filename;
        return thing;
    }
}

答案 1 :(得分:7)

嗯,有几个潜力 - 什么被认为是elegent取决于使用场景。

  • 静态工厂方法,调用私有构造函数。

    static Thing thingWithFileName(string fileName)
    
  • 为其中一个参数创建不同的类型,或使用内置函数。您可以使用System.IO.FileStream而不是字符串fileName。这也是更安全的类型,因为我不会意外地将错误的数据传递给错误的静态方法或字段。

  • 将第二个参数传递给构造函数,可以是enum或boolean,表示第一个参数的意图

    enum ThingType { FileName, ConnectionString }
    Thing(string str, ThingType type) ...
    
  • Subclass Thing,所以你有一个ConnectionTypeThing和一个FileBackedThing

  • 完全消除Thing做它的连接,并提供预先连接的数据源。所以你最终得到了

    Thing(InputStream dataSource)
    

    或类似的东西。

我的“优雅”资金可用于第一或第二个建议,但我需要更多的背景来满足任何选择。

答案 2 :(得分:5)

您可以将所有构造函数设为私有并创建工厂方法(类上的静态方法,如CreateFromConnectionString())。

答案 3 :(得分:5)

这些对我来说实际上看起来像是不同的“事物”,无论是与文件关联的类还是与数据库关联的类。我定义了一个接口,然后为每个接口分别实现。使用Factory生成正确的实现。

您可能需要更改设计的提示是,如果您的方法必须在执行所需操作之前决定是使用文件还是数据库。如果是这种情况,那么分成不同的类将是我的方式。

public interface IThing
{
   ... methods to do the things that Things do
}

public class FileThing : IThing
{
  ... file-based methods
}

public class DatabaseThing : IThing
{
  ... database-based methods
}

public static class ThingFactory
{
     public IThing GetFileThing( string name )
     {
         return new FileThing( name );
     }

     public IThing GetDatabaseThing( string connectionString )
     {
         return new DatabaseThing( connectionString );
     }
}

如果你有共同的行为,你可以选择定义一个包含默认/共同行为的抽象类,并从它派生而不是/除了界面。

答案 4 :(得分:1)

创建两个公共属性ConnectionString和FileName,然后使用它们来填充对象。

在C#中,您可以使用对象初始化器。像这样:

Thing thing = new Thing{FileName = "abc", ConnectionString = "123"};

答案 5 :(得分:0)

以下是一些解决方法。

有一个构造函数接受一个连接字符串,然后在接受字符串的类上有一个工厂方法。像这样:

public static Thing CreateThing(string fileName)

这个方法可以调用一个私有参数less constructor,你可以从那里获取它。

另一种选择是让枚举有两种类型。 FileName和ConnectionString。然后只需要一个带字符串的构造函数和枚举。然后根据枚举,您可以确定要走哪条路。

答案 6 :(得分:0)

我喜欢静态构造函数:

class Thing
{
   public static Thing NewConnection(string connectionString)
   {
       return new Thing(connectionString, true);
   }

   public static Thing NewFile(string fileName);
   {
        return new Thing(fileName, false);
   }
}
.
.
.
{
    var myObj = Thing.NewConnection("connect=foo");
    var Obj2 = Thing.NewFile("myFile.txt");
}

(未示出,但是直截了当地,使用额外的布尔参数实现Thing-Constructor)。