我有一组继承自我创建的抽象类的类。我想使用抽象类作为工厂来创建抽象类的具体实现的实例。
是否有任何方法可以隐藏除父类之外的所有代码中的构造函数。
我想基本上这样做
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
{
}
但是我想阻止任何人直接实例化2个具体的类。我想确保只有MakeAbstractClass()方法可以实例化基类。有没有办法做到这一点?
更新
我不需要从Abstract类外部访问ConcreteClassA或B的任何特定方法。我只需要Abstract类提供的公共方法。我真的不需要阻止Concrete类被实例化,我只是试图避免它,因为它们不提供新的公共接口,只是抽象类内部的一些非常特定的东西的不同实现。
对我而言,最简单的解决方案是make child classes as samjudson mentioned。我想避免这种情况,因为它会使我的抽象类'文件比我想要的大得多。我宁愿将课程分成几个文件进行组织。
我想这对此没有简单的解决方案......
答案 0 :(得分:6)
对我而言,最简单的解决方案是 让儿童班成为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(字符串args)
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()
{
}
}
答案 1 :(得分:3)
如果类在同一个程序集中,那么你不能让构造函数在内部吗?
答案 2 :(得分:2)
您可以创建子类子类,如下所示:
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这确实意味着类也被隐藏了。但据我所知,这是完全隐藏构造函数的唯一方法。
编辑:正如其他人提到的那样,使用Reflection可以完成同样的事情,这可能实际上更接近你想要的情况 - 例如上面的方法回复具体类在同一个文件里面抽象类,可能不是很方便。说过这种方式是一个很好的'Hack',如果具体类的数量和复杂性很低,那就太好了。
答案 3 :(得分:1)
不,我认为我们不能那样做。
答案 4 :(得分:1)
继accepted answer之后,如果你有一个公共接口并使私有类实现了接口,那么你可以返回一个指向接口的指针,然后你的父抽象类之外的任何人都可以使用它们(而仍然隐藏儿童班。)
答案 5 :(得分:0)
你真的需要这样做吗?如果您使用某种伪工厂模式而没有真正的设计需求,那么您只会使您的代码更难理解,维护和扩展。
如果您不需要这样做,只需实现真正的工厂模式。或者,更多ALTy,使用DI / IoC框架。
答案 6 :(得分:0)
您是否可以使用关键字partial
将类的代码拆分为多个文件?
答案 7 :(得分:0)
如果在单独的服务程序集中使用此类,则可以使用internal关键字。
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() {}
}
答案 8 :(得分:-2)
您需要做的是防止创建默认构造函数。如果类不在同一个程序集中,则internal可以更改为public。
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();
}
}