我正在尝试使泛型的继承层次结构起作用,而且我遇到了一些问题。
以下是一个例子:
interface IFoo {}
interface IFoo<T> : IFoo
{
T Data { get; }
}
class Foo : IFoo<int> { public int Data { get; set; } }
interface IBar {}
class Bar : IBar { }
abstract class LayerOne<T_FOO, T_BAR> where T_FOO : IFoo where T_BAR : IBar {}
abstract class LayerTwo<T_FOO> : LayerOne<T_FOO, Bar> where T_FOO : IFoo, new()
{
protected T_FOO _foo = new T_FOO();
public void Test1() { _foo.Data.Dump();} // Compiler error
}
class LayerThree : LayerTwo<Foo>
{
public void Test2() { _foo.Data.Dump();}
}
我正在尝试访问.Data
课程中的LayerTwo
。显然,由于IFoo
没有该属性,因此会出错。但是,如果我将T_FOO
的类型更改为IFoo<T>
,那么我必须将其定义为LayerThree
:
abstract class LayerTwo<T_FOO, T> : LayerOne<T_FOO, Bar> where T_FOO : IFoo<T>, new()
{
protected T_FOO _foo = new T_FOO();
public void Test1() { _foo.Data.Dump();}
}
class LayerThree : LayerTwo<Foo, int>
{
public void Test2() { _foo.Data.Dump();}
}
但具体Foo
实现的目的是已经知道它正在实现IFoo<int>
。 有什么方法可以让LayerTwo
了解Data
属性,而无需从Foo
查找并添加到LayerThree
的定义中?
我喜欢的是:
class LayerThree : LayerTwo<Foo> // Automatically realizes that the second generic is int
{
public void Test2() { _foo.Data.Dump();}
}
更新:事实证明,我实际上是在尝试在代码中实现两个相互矛盾的事情。实际LayerTwo
试图保持T_FOO
通用,但也创建了一个(抽象)方法,该方法需要IFoo<T>
中的特定类型。
因此,我要使用的解决方案就是使用继承自IFoo<T>
的接口并指定类型,但我接受Ondrej Tucny的答案,因为它 解决问题我问道。
答案 0 :(得分:3)
这与IEnumerable
/ IEnumerable<T>
的情况完全相同。您的弱类型界面IFoo
需要提供弱类型Data
:
public interface IFoo
{
object Data { get; }
}
public interface IFoo<T> : IFoo
{
new T Data { get; }
}
然后在实现中,其中一个将明确支持强类型访问:
public class IntFoo : IFoo<int>
{
public int Data { get { return -1; } }
object IFoo.Data { get { return Data; } }
}
现在您可以访问Data
,但是当实际类型T
未知时,您必须使用object
。