我的设计类似于此示例:
interface IFoo<T1>
{
IBar<T1> Bar { get; }
}
interface IFoo<T1, T2> : IFoo<T1>
{
new IBar<T1, T2> Bar { get; }
}
class Foo<T1> : IFoo<T1>
{
public IBar<T1> Bar { get; private set; }
public Foo(IBar<T1> bar)
{
Bar = bar;
}
}
class Foo<T1, T2> : Foo<T1>, IFoo<T1, T2>
{
public Foo(IBar<T1, T2> bar) : base(bar) { }
public new IBar<T1, T2> Bar { get{return base.Bar as IBar<T1, T2>;} }
}
interface IBar<T1>...
class Bar<T1> : IBar<T1>...
interface IBar<T1, T2> : IBar<T1>...
class Bar<T1, T2> : Bar<T1>, IBar<T1, T2>...
然后可以这样使用:
var bar = new Bar<int, int>();
var foo = new Foo<int, int>(bar);
或类似的话:
var bar = new Bar<int>();
var foo = new Foo<int>(bar);
甚至:
var bar = new Bar<int, int>();
var foo = new Foo<int>(bar);
唯一无效的组合是将派生最少的bar传递给派生最多的foo。
var bar = new Bar<int>();
var foo = new Foo<int, int>(bar); //does not work
调用基本构造函数时会强制转换为bar,访问派生类中的属性时会转换为bar,但这只是通过它们都支持的两个不同接口访问同一对象。
我实际上发现这种构造非常整洁和有效。这也很安全:如果您尝试弄乱参数,则强制转换将失败。
您是否发现此设计有任何缺陷,如果可以,该如何改进?