.NET泛型问题

时间:2011-07-27 16:38:38

标签: c# .net generics

有人可以解释为什么我收到编译错误要求显式转换?由于我限制了输出,我认为这是允许的,没有任何暴力。

**谢谢大家。这是我提出问题的方式。 **

public interface IQuery<TInput, TOutput>
{
    TOutput Execute(TInput input);
}

public abstract class PagedQuery<TInput, TOutput> : IQuery<TInput, TOutput>
    where TOutput : IEnumerable<TOutput>
{
    public TOutput Execute(TInput input)
    {
        return Enumerable.Empty<TOutput>(); // error here..
    }
}

4 个答案:

答案 0 :(得分:9)

Enumerable.Empty<TOutput>()返回 IEnumerable<TOutput>的实现。仅仅因为TOutput 实现IEnumerable<TOutput>并不意味着您可以将任何 IEnumerable<TOutput>值转换为TOutput

我同意那些评论员的观点,他们认为限制TOutput返回序列本身就很奇怪了。顺便说一下。

我怀疑你真的想要这样的东西:

public abstract class PagedQuery<TInput, TElement>
    : IQuery<TInput, IEnumerable<TElement>>
{
    public IEnumerable<TElement> Execute(TInput input)
    {
        return Enumerable.Empty<TElement>();
    }
}

这对我来说更有意义。

编辑:我已重命名了type参数以使其更清晰。因此对于IQuery<,>TOutput=IEnumerable<TElement> - 所以PagedQuery返回一系列元素,而不是 pages 的序列,每个元素本身都是一系列页面,每一个都是无限的页面序列。

答案 1 :(得分:3)

编译器希望您返回TOutput而不是IEnumerable<TOutput>,您的约束指定TOutput继承自IEnumerable<TOutput>并不重要不一样。

如果可以,将Execute方法中的接口类型和抽象类更改为IEnumerable<TOutput>可以解决编译器问题。

答案 2 :(得分:0)

考虑将TOutput移动为您要返回的IEnumerable的有效负载:

    public interface IQuery<TInput, TOutput>
    {
        IEnumerable<TOutput> Execute(TInput input);
    }

    public abstract class PagedQuery<TInput, TOutput> : IQuery<TInput, TOutput>
    {
        public IEnumerable<TOutput> Execute(TInput input)
        {
            return Enumerable.Empty<TOutput>();
        }
    }

答案 3 :(得分:0)

我认为您尝试做的是创建一个泛型类PagedQuery,其中输出始终是可枚举的,而通用IQuery接口不一定产生可枚举的输出。

我想你可以写这个来实现这个目标:

// Define other methods and classes here
public interface IQuery<TInput, TOutput>
{
    TOutput Execute(TInput input);
}

public class PagedQuery<TInput, TOutput> : IQuery<TInput, IEnumerable<TOutput>>
{
    public IEnumerable<TOutput> Execute(TInput input)
    {
        return Enumerable.Empty<TOutput>();
    }
}

现在你可以写

var query = new PagedQuery<int, int>();
IEnumerable<int> output = query.Execute(0);