2012-11-21 7 views
9

Utilizzo di Delphi XE-2 (tutti gli aggiornamenti applicati).Perché posso passare una var di tipo X ad un parametro di array aperto di quel tipo?

Mi aspetto che il seguente codice generi errori di compilazione sulle chiamate DoSomething e DoInteger, ma non lo fa.

program OpenArrayQuestion; 

{$APPTYPE CONSOLE} 
{$R *.res} 

uses 
    System.SysUtils; 

type 
    IComposite = interface(IInterface) 
    ['{1AC3CF6A-1316-4838-B67B-9FB075585C1E}'] 
    end; 

    IComposite<T: IComposite> = interface(IComposite) 
    ['{7F866990-9973-4F8E-9C1F-EF93EF86E8F2}'] 
    end; 

function DoSomething(const aData: array of IComposite): Boolean; 
begin 
    Result := True; 
end; 

function DoInteger(const aData: array of Integer): boolean; 
begin 
    Result := True; 
end; 

var 
    FData: IComposite; 
    FInteger: Integer; 
begin 
    DoSomething(FData); 
    DoInteger(FInteger); 
end. 

Qualcuno può spiegare perché posso passare FData/FInteger - sia solo singole variabili, ad un parametro open array dei rispettivi tipi senza metterlo tra [] 's e senza il compilatore barfing a destra verso di me?

Ho pensato che potrebbe avere a che fare con una serie di interfacce, o anche con i generici coinvolti, ma il compilatore accetta anche un intero passato a un array aperto di numeri interi.

risposta

7

Il compilatore è un po 'trascurato perché non vi è alcuna ambiguità nel farlo.

consideri il seguente:

program OpenArrays; 

{$APPTYPE CONSOLE} 

procedure Test1(i: Integer); overload; 
begin 
    Writeln('Test1Integer'); 
end; 

procedure Test1(i: array of Integer); overload; 
begin 
    Writeln('Test1OpenArray'); 
end; 

procedure Test2(i: array of Integer); 
begin 
    Writeln('Test2'); 
end; 

var 
    i: Integer; 

begin 
    Test1(i); 
    Test1([i]); 
    Test2(i); 
    Readln; 
end. 

che produce questo output:

 
Test1Integer 
Test1OpenArray 
Test2 

ho sovraccaricato Test1 modo che v'è una versione che riceve un numero intero, e una versione che riceve un open matrice di numeri interi. In questa situazione, la chiamata Test1(i) passa al sovraccarico che riceve solo un numero intero. D'altra parte, posso chiamare Test2 che riceve un array aperto, semplicemente passando un numero intero.


Credo che questo comportamento non sia documentato nello language guide. Tuttavia, @hvd trovato quanto segue nella documentation for compiler error E2192 (sottolineatura mia):

argomenti Apri matrice devono essere alimentati con una variabile di matrice reale, una matrice o un costruito singola variabile dell'elemento dell'argomento tipo.

+3

È nella documentazione per l'errore E2192: "Gli argomenti di array aperti devono essere forniti con una variabile di array effettiva, un array costruito o una variabile singola del tipo di elemento dell'argomento." Non lo vedo nella documentazione in cui mi aspettavo di trovarlo, però. – hvd

+1

Beh, sarò dannatamente ... Grazie David. E grazie a @hvd per aver recuperato la documentazione di errore. Non esattamente dove ti aspetteresti di trovare tali informazioni. –

+1

@hvd Ben giocato davvero. Mi piacerebbe sapere, come mai l'hai trovato? –

Problemi correlati