【问题标题】:How do i abstract TChild from Parent<TParent,TChild>我如何从 Parent<TO Parent,Child> 抽象 Child
【发布时间】:2016-03-22 18:59:32
【问题描述】:

我有 2 个使用泛型的接口

我的子界面如下所示:

public interface ICell<TContent>
{
    TContent Content { get; }

    string Background { get; }
    string Foreground { get; }

}

和我的父界面如:

public interface IRow<TRowHeader,TContent>
{
    TRowHeader RowHeader { get; }

    IList<ICell<TContent>> Zellen {get;}
}

当我基于 IRow 创建一个类时,我必须设置我想要避免的 TContent。所以我想知道如何从我的IRow 中抽象出这个泛型?

最后我希望能够写作

public class MyCell : ICell<string>
{
    public string Background { get; set; }
    public string Content { get; set; }
    public string Foreground { get; set; }
}

public class MyRow: IRow<string,MyCell>
{
    public string RowHeader { get; set; }
    public IList<MyCell> Zellen { get; set; }
}

【问题讨论】:

  • 你需要使用不同的接口,你不能只是省略泛型参数并替换具体类。你为什么不做类似MyRow : IRow&lt;string, MyCell&gt;的事情?
  • @RonBeyer 谢谢我会更新我的问题

标签: c# generics design-patterns interface


【解决方案1】:

为了做你所要求的,你必须稍微改变你的IRow界面:

public interface IRow<TRowHeader, TCell>
{
    TRowHeader RowHeader { get; }

    IList<TCell> Zellen { get; }
}

发生的情况是您需要确定IList 可以容纳TCell 类型。你不能在这里说TCellICell&lt;T&gt;(因为你必须在类型列表中定义T),但是你可以添加另一个接口并这样做:

public interface ICell 
{ 
    string Background { get; }
    string Foreground { get; }
}

public interface ICell<TContent> : ICell
{
    TContent Content { get; }
}

这将允许您在 IRow TCell 类型上创建约束:

public interface IRow<TRowHeader, TCell> where TCell : ICell
{
    TRowHeader RowHeader { get; }

    IList<TCell> Zellen { get; }
}

现在,您可以定义您的 MyRow

public class MyRow : IRow<string, MyCell>
{
    public string RowHeader { get; set; }
    public IList<MyCell> Zellen { get; set; }
}

并且所有的约束都满足了。

这有点冗长,如果您可以放弃非泛型 ICell 并指定 ICell&lt;T&gt; 其中 TIRow 约束中的任何类型,那就太好了,但是目前在 C# 中是不可能的。

【讨论】:

    【解决方案2】:

    我的理解是: - 单元格具有通用内容(TContent) - 一行是一个单元列表(TCell)。 TCell 本身可以是通用的。

    所以你的代码看起来像这样:

    public interface ICell<TContent>
    {
        TContent Content { get; }
    
        string Background { get; }
        string Foreground { get; }
    }
    public interface IRow<TRowHeader,TCell>
    {
        TRowHeader RowHeader { get; }
        IList<TCell> Zellen {get;}
    }
    

    然后,

    public class MyCell : ICell<string>
    {
        public string Background { get; set; }
        public string Content { get; set; }
        public string Foreground { get; set; }
    }
    
    public class MyRow: IRow<string,MyCell>
    {
        public string RowHeader { get; set; }
        public IList<MyCell> Zellen { get; set; }
    }
    

    【讨论】:

    • 这里唯一的问题是IRow 的继承者可以做这样的事情:public class MyNewRow : IRow&lt;string, int&gt; { ... },这是完全合法的代码。没有什么说TCell 必须是ICell&lt;T&gt;
    猜你喜欢
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多