C#中的继承树和受保护的构造函数

鉴于以下继承树,以一种有效的方式实现它的最佳方式是什么?

abstract class Foo<T> : IEnumerable<T>
{
    public abstract Bar CreateBar();
}

class Bar<T> : Foo<T>
{
    // Bar's provide a proxy interface to Foo's and limit access nicely.
    // The general public shouldn't be making these though, they have access
    // via CreateBar()
    protected Bar(Foo base)
    {
        // snip...
    }
}

class Baz<T> : Foo<T>
{
    public Bar CreateBar()
    {
        return new Bar(this);
    }
}

这失败了: 'Bar.Bar()' is inaccessible due to its protection level

我不想让构造函数公开,只有从Foo继承的类才能创建BarBar是一个专门的Foo ,任何类型的Foo都应该能够创建一个。 公共内部在这里是一个'选项',因为Foo的大多数预定义扩展都将在DLL内部,但我认为这是一个马虎的答案,因为任何后来谁想要创建他们自己的FooBaz类型的人(很可能会发生)将会被默认的CreateBar()实现所困住,这可能会或可能不会满足他们的需求。

也许有一种重构这种方式使其工作很好? 我正在试图设计这个墙,让我的头在墙上,所以它会工作。

编辑(更多信息):

稍微更具体一点:Foo实现了IEnumerable和长话短说,Bar提供了相同的接口,但是对于该枚举对象的有限子集。 所有Foo应该能够创建自己的子集(即Bar)并将其返回。 但我不希望每个想要实施Foo的人都不必担心这一点,因为Bar会代理并担心限制范围等。


好的,新的答案:

  • 拆分栏到一个界面和一个具体的类。
  • 用IBar表达公共抽象方法。
  • 使Bar成为Foo中的一个私有嵌套类,实现IBar。 给它一个你可以从Foo调用的内部构造函数。
  • 在Foo中写一个受保护的方法,从它自己创建一个Bar实例。 派生自Foo的类可以使用它来实现抽象方法,只要代理是足够好的,而需求更复杂的类可以直接实现IBar。 您甚至可以将抽象方法更改为虚拟方法,并默认从“this”创建一个新的Bar。
  • 编辑:对此的一个变体将使Foo中的Bar成为受保护的嵌套类,并带有公共构造函数。 这样,任何派生类都可以为自己实例化,但没有不相关的类将能够“看到”它。 你仍然需要将接口与实现分离(以便接口可以公开),但我认为这是一件好事。


    你能否在Bar中使Baz成为嵌套类型? 这是您获得Bar的更多途径的唯一方式。 只有拥有相同的父类才能访问Foo的受保护成员,而且Foo对Bar没有特殊的访问权限。 我怀疑在嵌套类型中还有其他曲折的方法,但对于维护工程师来说真的会很不愉快。

    这是一个非常奇怪的设计,但强制一个派生类创建一个从相同基类派生的不同类的实例。 那真的是你需要的吗? 也许如果你用更具体的术语来说,想出其他设计会更容易。


    您可以通过Foo中的嵌套类型访问Bar的构造函数:

    abstract class Foo<T> : IEnumerable<T>
    {
      public abstract Bar<T> CreateBar();
    
      protected Bar<T> CreateBar(Foo<T> f) { return new FooBar(f); }
    
      private class FooBar : Bar<T> 
       { public FooBar(Foo<T> f) : base(f) {}   
       }
    }
    
    class Bar<T> : Foo<T>
    { protected Bar(Foo<T> @base) {}
    }
    
    class Baz<T> : Foo<T>
    {
        public override Bar<T> CreateBar() 
        {
            return CreateBar(this);
        }
    }
    
    链接地址: http://www.djcxy.com/p/82177.html

    上一篇: Inheritance trees and protected constructors in C#

    下一篇: Creating the Singleton design pattern in PHP5