有没有办法让构造函数只对C#中的父类可见?

我有一个inheritance自我创建的抽象类的类的集合。 我想使用抽象类作为工厂来创建抽象类的具体实现的实例。

有没有办法隐藏除父类之外的所有代码的构造函数。

我想基本上这样做

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()方法可以实例化基类。 有没有办法做到这一点?

UPDATE
我不需要从Abstract类外部访问ConcreteClassA或B的任何特定方法。 我只需要Abstract类提供的公共方法。 我真的不需要阻止Concrete类被实例化,我只是试图避免它,因为它们不提供新的公共接口,只是抽象类内部的一些非常具体的事物的不同实现。

对我来说,最简单的解决方案是将子类作为samjudson提到 。 我想避免这种情况,因为它会使我的抽象类’文件比我想要的要大很多。 我宁愿将课程分成几个文件进行组织。

我猜这个没有简单的解决方案……

您可以创建子类子类,如下所示:

 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可以完成同样的事情,这可能实际上更接近你想要的情况 – 例如上面的方法回复与Abstract类在同一文件中的具体类,这可能不是很方便。 说过这种方式是一个很好的’Hack’,如果具体类的数量和复杂性很低,那就太好了。

对我来说,最简单的解决方案是将子类作为samjudson提到。 我想避免这种情况,因为它会使我的抽象类’文件比我想要的要大很多。 我宁愿将课程分成几个文件进行组织。

没问题,只需使用partial关键字,您就可以将内部类分成任意数量的文件。 您不必将其保留在同一文件中。

上一个答案:

这是可能的,但只有反思

 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 where T : AbstractClass { public static T MakeAbstractClass() { T value = (T)Activator.CreateInstance(typeof(T), true); // your processing logic return value; } } public class ConcreteClassA : AbstractClass { private ConcreteClassA() { } } public class ConcreteClassB : AbstractClass { private ConcreteClassB() { } } 

如果类在同一个程序集中,那么你不能让构造函数内部化吗?

不,我认为我们不能那样做。

从接受的答案开始 ,如果你有一个公共接口并使私有类实现接口,那么你可以返回一个指向接口的指针,然后你的父抽象类之外的任何人都可以使用它们(同时仍然隐藏子类) )。

你真的要这样做吗? 如果您使用某种伪工厂模式而没有真正的设计需求,那么您只会使您的代码更难理解,维护和扩展。

如果您不需要这样做,只需实现一个真正的工厂模式。 或者,更多ALTy,使用DI / IoC框架。

你不能使用关键字partial来将类的代码拆分成许多文件吗?

如果在单独的服务程序集中使用此类,则可以使用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() {} } 

您需要做的是阻止创建默认构造函数。 如果类不在同一个程序集中,则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(); } }