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

Doo*_*gal 26 .net c#

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

public Thing(string connectionString)

public Thing(string fileName)
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*ght 43

您可以使用命名的构造函数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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*ght 7

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

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

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

  • 将第二个参数传递给构造函数,可以是枚举或布尔值,表示第一个参数的意图

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

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

    Thing(InputStream dataSource)
    
    Run Code Online (Sandbox Code Playgroud)

    或类似的东西.

我的"优雅"钱可以用于第一个或第二个建议,但我需要更多的背景来满足任何选择.


Bri*_*ian 5

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


tva*_*son 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 );
     }
}
Run Code Online (Sandbox Code Playgroud)

如果您有共同的行为,您可以选择定义一个包含默认/公共行为的抽象类,并从它派生而不是/除了接口.