题
我有一个继承自我创建的抽象类的类的集合。我想使用抽象类作为工厂来创建抽象类的具体实现的实例。
有没有办法对除父类之外的所有代码隐藏构造函数。
我基本上想这样做
public abstract class AbstractClass
{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return new ConcreteClassA();
if (args == "b")
return new ConcreteClassB();
}
}
public class ConcreteClassA : AbstractClass
{
}
public class ConcreteClassB : AbstractClass
{
}
但我想阻止任何人直接实例化这两个具体类。我想确保只有 MakeAbstractClass() 方法可以实例化基类。有什么办法可以做到这一点吗?
更新
我不需要从抽象类外部访问 ConcreteClassA 或 B 的任何特定方法。我只需要我的抽象类提供的公共方法。我真的不需要阻止具体类被实例化,我只是想避免它,因为它们没有提供新的公共接口,只是抽象类内部一些非常具体的东西的不同实现。
对我来说,最简单的解决方案是 正如萨姆贾德森提到的那样开设儿童班. 。然而,我想避免这种情况,因为它会使我的抽象类文件比我想要的大得多。我宁愿将类分成几个文件以便组织。
我想这个问题没有简单的解决方案......
解决方案
您可以将子类设为子类,如下所示:
public abstract class AbstractClass
{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return new ConcreteClassA();
if (args == "b")
return new ConcreteClassB();
}
private class ConcreteClassA : AbstractClass
{
}
private class ConcreteClassB : AbstractClass
{
}
}
@Vaibhav 这确实意味着这些类也是隐藏的。但据我所知,这是完全隐藏构造函数的唯一方法。
编辑:正如其他人提到的,可以使用反射来完成同样的事情,这实际上可能更接近您想要的情况 - 例如上面的方法回复与抽象类位于同一文件内的具体类,这可能不是很方便。话虽如此,这种方式是一个很好的“Hack”,如果具体类的数量和复杂性较低,那么这种方式就很好。
其他提示
对我来说,最简单的解决方案是正如Samjudson提到的。我想避免这种情况,但是因为这会使我的抽象类“文件”比我想要的要大得多。我宁愿将课程分成几个文件以进行组织。
没问题,直接使用 部分的 关键字,您可以将内部类拆分为任意多个文件。您不必将其保存在同一个文件中。
之前的回答:
这是可能的,但只能通过反射
public abstract class AbstractClass
{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassA), true);
if (args == "b")
return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassB), true);
}
}
public class ConcreteClassA : AbstractClass
{
private ConcreteClassA()
{
}
}
public class ConcreteClassB : AbstractClass
{
private ConcreteClassB()
{
}
}
这是另一种模式,没有难看的 MakeAbstractClass(字符串参数)
public abstract class AbstractClass<T> where T : AbstractClass<T>
{
public static T MakeAbstractClass()
{
T value = (T)Activator.CreateInstance(typeof(T), true);
// your processing logic
return value;
}
}
public class ConcreteClassA : AbstractClass<ConcreteClassA>
{
private ConcreteClassA()
{
}
}
public class ConcreteClassB : AbstractClass<ConcreteClassB>
{
private ConcreteClassB()
{
}
}
如果这些类位于同一个程序集中,是否不能将构造函数设为内部构造函数?
不,我认为我们做不到。
继从 接受的答案, ,如果您有一个公共接口并使私有类实现该接口,那么您可以返回一个指向该接口的指针,并且父抽象类之外的任何人都可以使用它们(同时仍然隐藏子类)。
你实际上吗 需要 去做这个?如果您使用某种伪工厂模式而没有真正的设计需要,那么您只会使代码更难理解、维护和扩展。
如果不需要这样做,只需实现真正的工厂模式即可。或者,更多 ALTy,使用 DI/IoC 框架。
不能用关键字吗 partial
将一个类的代码拆分为多个文件?
如果您在单独的服务程序集中使用此类,则可以使用内部关键字。
public class AbstractClass
{
public AbstractClass ClassFactory(string args)
{
switch (args)
{
case "A":
return new ConcreteClassA();
case "B":
return new ConcreteClassB();
default:
return null;
}
}
}
public class ConcreteClassA : AbstractClass
{
internal ConcreteClassA(){ }
}
public class ConcreteClassB : AbstractClass
{
internal ConcreteClassB() {}
}
您需要做的是防止创建默认构造函数。如果类不在同一个程序集中,则可以将内部更改为公共。
public abstract class AbstractClass{
public static AbstractClass MakeAbstractClass(string args)
{
if (args == "a")
return ConcreteClassA().GetConcreteClassA();
if (args == "b")
return ConcreteClassB().GetConcreteClassB();
}
}
public class ConcreteClassA : AbstractClass
{
private ConcreteClassA(){}
internal static ConcreteClassA GetConcreteClassA(){
return ConcreteClassA();
}
}
public class ConcreteClassB : AbstractClass
{
private ConcreteClassB(){}
internal static ConcreteClassB Get ConcreteClassB(){
return ConcreteClassB();
}
}