减少通用参数

时间:2014-01-07 17:12:38

标签: c# generics

我正在尝试使泛型的继承层次结构起作用,而且我遇到了一些问题。

以下是一个例子:

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的答案,因为它 解决问题我问道。

1 个答案:

答案 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