【问题标题】:Calling a Method Using a Nested Generic Type使用嵌套泛型类型调用方法
【发布时间】:2018-07-17 14:10:40
【问题描述】:

我想开发一个通用管道。这意味着我调用一个元素,然后调用下一个元素,等等。就它而言,它按预期的方式工作。 现在我想开发一个抽象类(如果 Tinput / TOutput 是一个列表)通过抽象方法 ProcessOne 处理元素。 我知道某些东西必须与泛型类型有关。 不幸的是,C# 不喜欢它。我究竟做错了什么?可能还有更好的方法来做到这一点(随时提供不同的方法)。

public interface IPipeline<out TOutput>
{
    TOutput Process();
}

public abstract class PipeItem<TInput, TOutput> : IPipeline<TOutput>
{
    protected readonly IPipeline<TInput> nextPipeItem;

    protected PipeItem(IPipeline<TInput> nextPipeItem)
    {
        this.nextPipeItem = nextPipeItem;
    }

    public abstract TOutput Process();
}

public abstract class CollectionPipe<TInput, TOutput> : PipeItem<TInput, TOutput> 
        where TInput : List<TInput>
        where TOutput : List<TOutput>
{
    protected CollectionPipe(IPipeline<TInput> nextPipeItem) : base(nextPipeItem)
    {
    }

    public override TOutput Process()
    {
        return nextPipeItem.Process().Select(ProcessOne).ToList();
    }

    protected abstract TOutput ProcessOne(TInput input);

}

public class SomeImplementation : CollectionPipe<List<string> , List<char[]>> {

    public SomeImplementation() : base(new SomeNextPipe())
    {
    }

    protected override char[] ProcessOne(string input){
        return input.ToCharArray();
    }
}

【问题讨论】:

  • 这个约束where TInput : List&lt;TInput&gt; 没有多大意义。你是说TInput 必须是List&lt;TInput&gt;
  • 是的,这正是我想说的。它必须是一个列表,否则该原则不起作用。列表中的每个项目都将使用 ProcessOne 方法进行处理。 (参见 Class SomeImplementation)问题也会存在(我猜)因为那里也使用了泛型参数 TInput/TOutput,这是不正确的。

标签: c# generics collections


【解决方案1】:

我不完全确定这是否是你想要的,但它至少应该给你一些指导。

与其说TInput/TOutput 必须是它们自己的集合,不如说CollectionPipe 实现了PipieItemTInputTOutput 的集合:

public abstract class CollectionPipe<TInput, TOutput> : PipeItem<List<TInput>, List<TOutput>>
{
    protected CollectionPipe(IPipeline<List<TInput>> nextPipeItem) : base(nextPipeItem)
    {
    }

    public override List<TOutput> Process()
    {
        return nextPipeItem.Process().Select(ProcessOne).ToList();
    }

    protected abstract TOutput ProcessOne(TInput input);

}

然后,实现可以只说它们输入和输出的类型,已经知道它们是集合(因为它们实现了CollectionPipe 而不仅仅是PipeItem

public class SomeImplementation : CollectionPipe<string, char[]>
{

    public SomeImplementation() : base(/*something here*/)
    {
    }

    protected override char[] ProcessOne(string input)
    {
        return input.ToCharArray();
    }
}

【讨论】:

  • 非常感谢。在此期间,我以同样的方式解决了它。但另一个普遍的问题。如果我们使用 List 限制泛型类型,我可以提取该类型以便我可以使用该类型调用方法吗?例如 List 和方法 DoSomething(ABC)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多