2012-10-02 17 views
7

Estoy tratando de escribir una función genérica que acepte tipos de parámetros coincidentes.
Delphi sí infiere el parámetro de tipo correctamente en el caso simple de argumentos simples.tipo de inferencia basada en el tipo de argumento genérico (Delphi)

por ejemplo:

type 
    TFoo = class 
    function Pair<T>(e1, e2: T): TList<T>; 
    end; 

llamar a esto con aFoo.Pair(1, 2); funciona perfectamente bien, pero cuando cambio la firma parámetro a un tipo genérico

type 
    TFoo = class 
    function InsertInto<T>(aList: TList<T>; aVal: T): TList<T>; 
    end; 

y trato de llamarlo
aFoo.InsertInto(TList<String>.Create, 'bar');

, entonces el compilador se queja al respecto:
E2010 Incompatible types: 'Generics.Collections.TList<uTest.TFoo.InsertInto.T>' and 'Generics.Collections.TList<System.String>'

¿Hay alguna manera de que pueda escribir este método (o uno similar), de modo que el cliente no tenga que especificar el parámetro de tipo?
aFoo.InsertInto<String>(TList<String>.Create, 'bar');

+0

Creo que el mensaje de error le da una pista de que la inferencia de tipo no hará el trabajo aquí. Claramente es un problema más difícil para el sistema de inferencia del compilador que el ejemplo simple en la parte superior de la Q. –

+0

intentar hacer un primer parámetro ValT: tal vez eso haría más fácil el compilador, pero la posibilidad es muy muy pobre –

+0

reemplazar "cadena "con" strign "y disfruta de E2010 Tipos incompatibles: 'System.Generics.Collections.TList ' y 'Boolean' –

Respuesta

5

Supongo que viene de la naturaleza fuertemente tipada de Delphi.
uTest.TFoo.InsertInto.T es equivalente a System.String pero es realmente un tipo diferente.

Al igual que en este ejemplo donde Int1 y Int2 no son del mismo tipo:

var 
    Int1: array[1..10] of Integer; 
    Int2: array[1..10] of Integer; 
     ... 
    Int1 := Int2; // <== BOOM! E2008 Incompatible types (in XE2) 

El problema real no es la inferencia de tipos, pero con los tipos no es compatible por las estrictas reglas de Pascal/Delphi .

+1

Eso suena muy plausible. Una pequeña selección de liendres. De lo que estás hablando es de identidad de tipo y compatibilidad, en lugar de sistemas de tipo fuerte/débil. –

+2

También podría ser que el tipo de la cadena literal ''bar' no sea' System.String', al menos no todavía. el tipo de cadena literal es bastante fluido; el compilador le asigna el tipo que necesita tener, al menos cuando sabe qué tipo necesita. Piense en cómo el mismo literal de cadena se puede pasar como UnicodeChar, PAnsiChar, WideString o ShortString, todo desde el mismo texto en el código. Por lo tanto, es posible que 'uTest.TFoo.InsertInto.T' en realidad represente una media docena de tipos diferentes, y el compilador no puede elegir el "mejor". –

+0

Tampoco funciona con literales enteros, aunque eso podría tener una razón similar (Byte vs. Integer vs. Cardinal). –

Cuestiones relacionadas