Qualcuno sa se è possibile definire l'equivalente di un "caricatore di classi personalizzate java" in .NET?Equivalente di caricatori di classi in .NET
Per dare un po 'di storia:
Io sono nel processo di sviluppo di un nuovo linguaggio di programmazione che gli obiettivi del CLR, chiamato "Liberty". Una delle caratteristiche del linguaggio è la sua capacità di definire "costruttori di tipi", che sono metodi che vengono eseguiti dal compilatore in fase di compilazione e generano tipi come output. Essi sono una sorta di una generalizzazione dei farmaci generici (la lingua non ha generici normali in esso), e consentire il codice come questo da scrivere (in "Libertà" sintassi):
var t as tuple<i as int, j as int, k as int>;
t.i = 2;
t.j = 4;
t.k = 5;
Dove "tupla" è definito in questo modo :
public type tuple(params variables as VariableDeclaration[]) as TypeDeclaration
{
//...
}
in questo particolare esempio, il tipo di costruttore di tuple
fornisce qualcosa di simile a tipi anonimi in VB e C#.
Tuttavia, a differenza dei tipi anonimi, "tuple" hanno nomi e possono essere utilizzati all'interno delle firme dei metodi pubblici.
Ciò significa che ho bisogno di un modo per il tipo che alla fine finisce per essere emesso dal compilatore per essere condivisibile tra più assiemi. Per esempio, io voglio
tuple<x as int>
definito Montaggio A finire per essere dello stesso tipo di tuple<x as int>
definito in Assemblea B.
Il problema con questo, naturalmente, è che Assemblea A e B Assemblea stanno per essere compilati in momenti diversi, il che significa che entrambi finiranno per emettere le proprie versioni incompatibili del tipo di tupla.
Ho guardato in utilizzando una sorta di "cancellazione del tipo" per fare questo, in modo che io avrei una libreria condivisa con un gruppo di tipi come questo (questa è la sintassi "Libertà"):
class tuple<T>
{
public Field1 as T;
}
class tuple<T, R>
{
public Field2 as T;
public Field2 as R;
}
e quindi reindirizzare l'accesso dai campi di tupla i, j, k a Field1
, Field2
e Field3
.
Tuttavia, questa non è un'opzione praticabile. Ciò significherebbe che al momento della compilazione tuple<x as int>
e tuple<y as int>
risulterebbero di tipo diverso, mentre in fase di runtime sarebbero trattati come lo stesso tipo. Ciò causerebbe molti problemi per cose come l'uguaglianza e l'identità del tipo. Questo è troppo dispersivo di un'astrazione per i miei gusti.
Altre opzioni possibili sarebbero utilizzare "oggetti borsa di stato". Tuttavia, l'uso di una borsa di stato vanificherebbe l'intero scopo di avere il supporto per "costruttori di tipi" nella lingua. L'idea è di abilitare "estensioni del linguaggio personalizzate" per generare nuovi tipi in fase di compilazione che il compilatore può eseguire con il controllo di tipo statico.
In Java, questo può essere fatto utilizzando caricatori di classe personalizzati. Fondamentalmente il codice che usa i tipi di tuple potrebbe essere emesso senza effettivamente definire il tipo sul disco. Si potrebbe quindi definire un "caricatore di classi" personalizzato che genererebbe dinamicamente il tipo di tupla in fase di runtime. Ciò consentirebbe il controllo di tipo statico all'interno del compilatore e unificerebbe i tipi di tupla attraverso i limiti di compilazione.
Sfortunatamente, tuttavia, il CLR non fornisce supporto per il caricamento personalizzato della classe.Tutto il carico nel CLR viene eseguito a livello di assemblaggio. Sarebbe possibile definire un assembly separato per ogni "tipo costruito", ma ciò comporterebbe molto rapidamente problemi di prestazioni (se molti assiemi con un solo tipo utilizzassero troppe risorse).
Quindi, quello che voglio sapere è:
E 'possibile simulare qualcosa di simile a Java classe di pale in .NET, dove posso emettere un riferimento a un tipo non-esistente e quindi generare dinamicamente un riferimento a quel tipo in fase di esecuzione prima del codice in cui è necessario eseguirlo?
NOTA:
* Io in realtà conosco già la risposta alla domanda, che fornisco come una risposta di seguito. Tuttavia, mi ci sono voluti circa 3 giorni di ricerca e un bel po 'di hacking su IL per trovare una soluzione. Ho pensato che sarebbe stata una buona idea documentarlo qui nel caso in cui qualcun altro si fosse imbattuto nello stesso problema. *
Oh wow, il primo post che ho mai pensato dovrebbe avere titoli di capitolo. Grande informazione! Grazie per la pubblicazione! –