我确信这一定是个常见问题。我有一个课程,在理想世界中会有以下构造函数
public Thing(string connectionString)
public Thing(string fileName)
显然这是不允许的,因为签名是相同的。有人知道这个问题的优雅解决方案吗?
答案 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)。