Come vengono implementati i farmaci generici?

16

Questa è la domanda dal punto di vista del compilatore internals.

Sono interessato ai generici, non ai modelli (C ++), quindi ho contrassegnato la domanda con C #. Non Java, perché AFAIK i generici in entrambe le lingue differiscono nelle implementazioni.

Quando guardo le lingue senza i generici è piuttosto semplice, puoi convalidare la definizione della classe, aggiungerla alla gerarchia e il gioco è fatto.

Ma cosa fare con la classe generica e, ancora più importante, come gestirne i riferimenti? Come assicurarsi che i campi statici siano singolari per istanze (ad esempio ogni volta che vengono risolti i parametri generici).

Diciamo che vedo una chiamata:

var x = new Foo<Bar>();

Aggiungo la nuova Foo_Bar class alla gerarchia?

Aggiornamento: Finora ho trovato solo 2 post pertinenti, tuttavia anche loro non entrano in molti dettagli nel senso "come farlo da soli":

posta greenoldman 28.10.2013 - 17:23
fonte

3 risposte

4

How to make sure that static fields are singular per instantiations (i.e. each time generic parameters are resolved).

Ogni istanza generica ha una propria copia del MethodTable (chiamato in modo confuso), che è dove sono memorizzati i campi statici.

Let's say I see a call:

var x = new Foo<Bar>();

Do I add new Foo_Bar class to hierarchy?

Non sono sicuro che sia utile pensare alla gerarchia delle classi come ad una struttura effettivamente esistente in fase di esecuzione, è più un costrutto logico.

Ma se consideri MethodTables, ognuno con un puntatore indiretto alla sua classe base, per formare questa gerarchia, allora sì, questo aggiunge una nuova classe alla gerarchia.

    
risposta data 28.10.2013 - 18:23
fonte
2

Vedo due domande concrete concrete là dentro. Probabilmente vorrai porre ulteriori domande correlate (come una domanda separata con un link a questo) per avere una comprensione completa.

In che modo vengono assegnati campi statici a istanze separate per istanza generica?

Bene, per i membri statici che non sono correlati ai parametri di tipo generico, questo è piuttosto facile (usa un dizionario mappato dai parametri generici al valore).

I membri (statici o non) che sono correlati ai parametri del tipo possono essere gestiti tramite cancellazione dei tipi. Basta usare qualunque sia il vincolo più strong (spesso System.Object ). Poiché le informazioni sul tipo vengono cancellate dopo il controllo del tipo di compilatore, ciò significa che i controlli del tipo di runtime non saranno necessari (sebbene i cast di interfaccia possano ancora esistere in fase di runtime).

Ogni istanza generica appare separatamente nella gerarchia dei tipi?

Non in generici .NET. È stata presa la decisione di escludere l'ereditarietà dai parametri di tipo, quindi risulta che tutte le istanze di un generico occupano lo stesso punto nella gerarchia di tipi.

Probabilmente è stata una buona decisione, perché la mancata ricerca di nomi da una classe base sarebbe stata incredibilmente sorprendente.

    
risposta data 28.10.2013 - 17:38
fonte
1

But what to do with generic class, and more importantly how handle references to it?

Il modo generale nel front-end del compilatore è di avere due tipi di istanze di tipo, il tipo generico ( List<T> ) e un tipo generico associato ( List<Foo> ). Il tipo generico definisce quali funzioni esistono, quali campi e ha riferimenti di tipi generici ovunque sia utilizzato T . Il tipo generico associato contiene un riferimento al tipo generico e un insieme di argomenti tipo. Ha sufficienti informazioni per generare un tipo concreto, sostituendo i riferimenti di tipo generico con Foo o qualunque sia l'argomento del tipo. Questo tipo di distinzione è importante quando stai facendo inferenza di tipo e devi inferire List<T> contro List<Foo> .

Invece di pensare a generici come i modelli (che costruiscono direttamente varie implementazioni), potrebbe essere utile considerarli come costruttori di tipi di linguaggio funzionali (dove gli argomenti generici sono come argomenti in una funzione che ti dà un tipo) .

Per quanto riguarda il back-end, non lo so davvero. Tutto il mio lavoro con i generici ha come target il CIL come back-end, quindi ho potuto compilarli nei generici supportati lì.

    
risposta data 03.07.2015 - 15:53
fonte

Leggi altre domande sui tag