Wer*_*ann 5 delphi generics type-inference
请考虑以下Delphi 2010中的通用实用程序类声明:
TEnumerableUtils = class
public
class function InferenceTest<T>(Param: T): T;
class function Count<T>(Enumerable: TEnumerable<T>): Integer; overload;
class function Count<T>(Enumerable: TEnumerable<T>; Filter: TPredicate<T>): Integer; overload;
end;
Run Code Online (Sandbox Code Playgroud)
不知何故,编译器类型推断似乎在这里有问题:
var
I: Integer;
L: TList<Integer>;
begin
TEnumerableUtils.InferenceTest(I); // no problem here
TEnumerableUtils.Count(L); // does not compile: E2250 There is no overloaded version of 'Count' that can be called with these arguments
TEnumerableUtils.Count<Integer>(L); // compiles fine
end;
Run Code Online (Sandbox Code Playgroud)
第一个调用按预期工作,T正确推断为Integer.
第二个调用不起作用,除非我也添加<Integer> - 然后它可以工作,如第三次调用中所见.我做错了什么或Delphi中的类型推断只是不支持这个(我不认为它是Java中的一个问题,这也是为什么期望它在Delphi中工作).
编译器需要进行模式匹配以推断参数类型; 它目前没有.编译器仅限于非常简单的推理 - 如果参数类型是类型参数类型,那么编译器可以解决它,但除此之外不多.
您的示例中的参数类型不是一个简单的类型参数,而是一个构造的泛型类型(它是使用方法的类型参数T构造的,但它的构造是一样的).编译器需要进行两次推断才能找出T的值.首先,需要看到构造类型的泛型类型是泛型类型的祖先TList<T>; 它还需要将构造类型的类型参数列表中的类型参数T与TList<T>祖先中的具体类型Integer进行匹配.