Кто-нибудь знает, можно ли определить эквивалент «java custom class loader» в .NET?Эквивалент загрузчиков классов в .NET
Чтобы дать немного фона:
Я нахожусь в процессе разработки нового языка программирования, нацеленного на CLR, которая называется «Свобода». Одной из особенностей языка является его способность определять «конструкторы типов», которые являются методами, которые выполняются компилятором во время компиляции и генерируют типы как выходные данные. Они являются своего рода обобщение генериков (язык имеет нормальные дженериков в нем), и позволяют код, как это будет написано (в «Либерти» синтаксис):
var t as tuple<i as int, j as int, k as int>;
t.i = 2;
t.j = 4;
t.k = 5;
Где «кортеж» определяется как так :
public type tuple(params variables as VariableDeclaration[]) as TypeDeclaration
{
//...
}
в этом конкретном примере, конструктор типа tuple
обеспечивает нечто похожее на анонимные типы в VB и C#.
Однако, в отличие от анонимных типов, «кортежи» имеют имена и могут использоваться внутри публичных сигнатур методов.
Это означает, что мне нужен способ для типа, который в конечном итоге испускается компилятором для совместного использования в нескольких сборках. Например, я хочу
tuple<x as int>
, определенные в Ассамблеи А в конечном итоге быть того же типа, как это определено в tuple<x as int>
Ассамблеи B.
Проблема с этим, конечно, является то, что Ассамблея А и B Ассамблеи собираются скомпилироваться в разное время, что означает, что они оба получат свои собственные несовместимые версии типа кортежа.
Я посмотрел в использовании своего рода «типа стирания», чтобы сделать это, так что я бы разделяемую библиотеку с кучей типов, как это (это синтаксис «Свобода»):
class tuple<T>
{
public Field1 as T;
}
class tuple<T, R>
{
public Field2 as T;
public Field2 as R;
}
а затем просто перенаправить доступ из полей i, j и k tuple в Field1
, Field2
и Field3
.
Однако это не является жизнеспособным вариантом. Это означало бы, что во время компиляции tuple<x as int>
и tuple<y as int>
в конечном итоге будут разными типами, а во время выполнения они будут рассматриваться как один и тот же тип. Это может вызвать множество проблем для таких вещей, как идентификация равенства и типа. Это слишком непроницаемо для абстракции для моих вкусов.
Другими возможными вариантами могут быть использование «предметов государственной сумки». Однако использование государственного мешка может победить всю цель поддержки «конструкторов типов» на языке. Идея состоит в том, чтобы включить «пользовательские расширения языка» для генерации новых типов во время компиляции, с которыми компилятор может выполнять проверку статического типа.
В Java это можно сделать с помощью пользовательских загрузчиков классов. В принципе, код, который использует типы кортежей, может быть выпущен без фактического определения типа на диске. Затем может быть определен пользовательский «загрузчик классов», который будет динамически генерировать тип кортежа во время выполнения. Это позволит проверять статический тип внутри компилятора и объединять типы кортежей между границами компиляции.
К сожалению, однако, CLR не поддерживает загрузку пользовательского класса.Вся загрузка в CLR выполняется на уровне сборки. Можно было бы определить отдельную сборку для каждого «построенного типа», но это очень быстро привело бы к проблемам с производительностью (наличие множества сборок с одним типом в них будет использовать слишком много ресурсов).
Итак, что я хочу знать:
Можно ли смоделировать что-то вроде Java загрузчиков классов в .NET, где я могу испускать ссылку на несуществующий тип в и затем динамически генерировать ссылка на этот тип во время выполнения перед тем, как код, который ему нужно использовать, запускается?
Примечание:
* Я на самом деле уже знаю ответ на вопрос, который я обеспечиваю как ответ ниже. Тем не менее, мне потребовалось около 3 дней исследований и довольно немного взлома IL, чтобы придумать решение. Я подумал, что было бы неплохо документировать его здесь, если бы кто-то другой столкнулся с той же проблемой. *
О, ничего себе, первое сообщение, которое я когда-либо думал, должно иметь главы. Отличная информация! Спасибо за сообщение! –