ang*_*son 7 c# generics type-inference nested-generics
可能重复:
没有使用通用扩展方法的类型推断
我有一个通用接口,以及它的两个具体实现.
然后我有一个方法,它是实现该接口的对象集合的扩展方法,它应该处理集合并返回已处理的集合.
处理操作不会更改对象也不会生成新对象,因此我希望该方法的输出与输入的类型相同.
换句话说,我不希望方法的输出是接口类型的集合,而是我传入的实际具体类型.
但是,这会在调用方法时导致类型推断出现问题.
我将用LINQPad示例说明:
void Main()
{
var intervals = new Interval<int>[]
{
new Interval<int>(),
new Interval<int>(),
};
var ordered1 = intervals.Process(); // error 1
// var ordered2 = Extensions.Process(intervals); // error 2
}
public static class Extensions
{
public static IEnumerable<TInterval> Process<TInterval, T>(
this IEnumerable<TInterval> intervals)
where TInterval : IInterval<T>
{
return intervals;
}
}
public interface IInterval<T> { }
public class Interval<T> : IInterval<T> { }
Run Code Online (Sandbox Code Playgroud)
这给了我以下两个编译时错误,你必须注释掉并在相关的行中激发两条消息:
错误1:
'Interval <int> []'不包含'Process'的定义,并且没有扩展方法'Process'接受类型'Interval <int> []'的第一个参数可以找到(按F4添加一个使用指令或汇编参考)错误2:
无法从用法推断出方法'Extensions.Process <TInterval,T>(System.Collections.Generic.IEnumerable <TInterval>)'的类型参数.尝试显式指定类型参数.
原因,或者我认为,在分析扩展方法是否合适时,编译器看起来并不"足够".
如果我将扩展方法更改为:
public static IEnumerable<IInterval<T>> Process<T>(
this IEnumerable<IInterval<T>> intervals)
{
return intervals;
}
Run Code Online (Sandbox Code Playgroud)
然后它编译,但因此输出是:
IEnumerable<IInterval<T>> result = ...
Run Code Online (Sandbox Code Playgroud)
并不是:
IEnumerable<Interval<int>> result = ...
Run Code Online (Sandbox Code Playgroud)
当然,如果我在调用时指定类型,如下所示:
var ordered = intervals.Process<IInterval<int>, int>();
Run Code Online (Sandbox Code Playgroud)
...然后它可以工作,但那并不是那么好(IMO.)有没有办法欺骗编译器为我推断类型?
基本上,我想:
归档时间: |
|
查看次数: |
126 次 |
最近记录: |