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

Dan*_*ert 5 c# oop 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
{
}
Run Code Online (Sandbox Code Playgroud)

但我想阻止任何人直接实例化2个具体的类.我想确保只有MakeAbstractClass()方法可以实例化基类.有没有办法做到这一点?

更新
我不需要从Abstract类外部访问ConcreteClassA或B的任何特定方法.我只需要Abstract类提供的公共方法.我并不真的需要防止被实例化的具体类,我只是想避免它,因为他们没有提供新的公共接口,只是不同的内部抽象类的一些非常具体的东西实现.

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

我想这没有简单的解决方案......

lub*_*sko 6

对我来说,最简单的解决方案是将子类作为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()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这是另一种模式,没有丑陋的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()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


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

@Vaibhav这确实意味着这些类也被隐藏了。但据我所知,这是完全隐藏构造函数的唯一方法。

编辑:正如其他人提到的,可以使用反射来完成同样的事情,这实际上可能更接近您想要的情况 - 例如上面的方法回复与抽象类位于同一文件内的具体类,这可能不太方便。话虽如此,这种方式是一个很好的“Hack”,如果具体类的数量和复杂性较低,那么这种方式就很好。