ReflectionOnlyLoad и GetField - PullRequest
2 голосов
/ 09 июня 2010

Если я загружаю сборку через Assembly.Load, я могу выполнять итерации по ее типам, искать определенный тип по typef (...). IsAssignableFrom и получать информацию о поле через GetField из типа.

AsЯ загружаю сборку только для отражения, я пробовал ReflectionOnlyLoad вместо загрузки.Первая проблема заключалась в том, что IsAssignableFrom всегда сообщал о ложном значении, но GetInterface делал свою работу.Вторая проблема, для которой я не нашел решения, - это GetField, всегда возвращающий ноль.

Ответы [ 3 ]

4 голосов
/ 07 мая 2015

Я столкнулся с той же проблемой, когда IsAssignableFrom всегда возвращал false, но провел некоторые эксперименты и нашел обходной путь. Ключ должен убедиться, что оба типа в сравнении находятся в контексте ReflectionlyOnly.

Другими словами, это вообще не работает:

var types = Assembly.ReflectionOnlyLoad(assemblyName).GetExportedTypes();
foreach( var t in types )
{
    bool check = SomeBaseType.IsAssignableFrom(t);
}

Это, кажется, всегда дает check=false, но я думаю, это потому, что t находится в контексте только для отражения, а SomeBaseType - нет.

Обходной путь, который я нашел, состоял в том, чтобы загрузить сборку базового класса в контексте только для отражения, а затем найти эквивалентный базовый тип в этом контексте. Затем мы можем сделать сравнение, где оба типа предназначены только для отражения:

var baseAssembly = Assembly.ReflectionOnlyLoad(typeof(SomeBaseType).Assembly.FullName);
var baseTypes = baseAssembly.GetExportedTypes();
var reflectionOnlyBaseType = Array.Find(baseTypes,(t)=>(t.FullName==typeof(SomeBaseType).FullName));
var types = Assembly.ReflectionOnlyLoad(assemblyName).GetExportedTypes();
foreach( var t in types )
{
    bool check = reflectionOnlyBaseType.IsAssignableFrom(t);
}

Кажется, это дает ожидаемый результат. Возможно, есть более эффективный способ добраться до этого контекста только для отражения без перезагрузки сборки (я не эксперт по C #), но это был самый простой способ, который я смог найти.

Похоже, что один и тот же подход работает как для IsSubclassOf, так и для IsAssignableFrom.

0 голосов
/ 22 июля 2016

Я использовал метод расширения, чтобы увидеть, равны ли два типа, что просто сравнивает свойство AssemblyQualifiedName.Это не пуленепробиваемый, но он определенно достаточно хорош:

public static bool ReflectionOnlyEquals(this Type type, Type otherType)
{
  return type.AssemblyQualifiedName == otherType.AssemblyQualifiedName;
}

Тогда я могу просто позвонить примерно так, например:

bool equal = currType.ReflectionOnlyEquals(typeof(string));
0 голосов
/ 09 июня 2010

Вы не можете использовать IsAssignableFrom со сборками, загруженными через RefelectionOnlyLoad / ReflectionOnlyLoadFrom, потому что IsAssignableFrom использует методы сравнения типа, такие как IsSubclassOf.Внутренне он делает вызов GetInterfaces через внутренний метод ImplementInterface, но это все.

Что касается вашего вызова GetField, какие флаги привязки вы передаете?Если вы не проходите мимо, является ли поле публичным?Как правило, по конструкции большинство полей должны быть закрытыми / внутренними, поэтому необходимо убедиться, что в метод GetField переданы правильные флаги привязки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...