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