Inheritance trees and protected constructors in C#
Given the following inheritance tree, what would be the best way of implementing it in a way that works?
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);
}
}
This fails with: 'Bar.Bar()' is inaccessible due to its protection level
.
I don't want the constructor being public, only classes that inherit from Foo
should be able to create Bar
s. Bar
is a specialised Foo
, and any type of Foo
should be able to create one. Public internal is an 'option' here, as the majority of the predefined extensions to Foo
will be internal to the DLL, but I consider this a sloppy answer, since anyone who comes along later who wants to create their own type of Foo
or Baz
(which is likely to happen) will be stuck with a default CreateBar()
implementation, which may or may not meet their needs.
Perhaps there is a way of refactoring this to make it work nicely? I'm banging my head on the wall trying to design this so it'll work though.
Edit (More info):
Slightly more concrete: Foo is implementing IEnumerable and long story short, Bar is providing the same interface, but to a limited subset of that enumerable object. All Foo's should be able to create subsets of themselves (ie. Bar) and return it. But I don't want to have everyone who ever wants to implement a Foo to have to worry about this, because Bar will do the proxying and worry about limiting the range, etc.
Okay, new answer:
EDIT: One variant on this would be to make Bar a protected nested class within Foo, with a public constructor. That way any derived class would be able to instantiate it for themselves, but no unrelated class would be able to "see" it at all. You'd still need to separate the interface from the implementation (so that the interface can be public) but I think that's a good thing anyway.
Would it be possible for you to make Baz a nested type within Bar? That's the only way you'll give it more access to Bar than it would otherwise have. Just having the same parent class only gives it access to protected members of Foo, and Foo doesn't have special access to Bar. I suspect there are other tortuous ways of doing this with nested types, but really it's going to be quite unpleasant for maintenance engineers.
It's quite an odd design though, to force one derived class to create an instance of a different class derived from the same base class. Is that really what you need? Perhaps if you put this in more concrete terms it would be easier to come up with alternative designs.
您可以通过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/82178.html
上一篇: C#中的好友类的情况
下一篇: C#中的继承树和受保护的构造函数