ReflectionOnlyLoad和GetField

时间:2010-06-09 17:08:24

标签: c#

如果我通过Assembly.Load加载程序集,我可以通过其类型进行迭代,通过typef(...)查找特定类型.IsAssignableFrom并通过类型从GetField获取字段信息。

当我加载程序集仅用于反射时,我尝试使用ReflectionOnlyLoad而不是加载。第一个问题是IsAssignableFrom总是报告错误,但GetInterface完成了这项工作。我找不到解决方案的第二个问题是GetField总是返回null。

3 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,IsAssignableFrom总是返回false,但做了一些实验并找到了解决方法。关键是要确保比较中的两种类型都在ReflectionlyOnly上下文中。

换句话说,这一般不起作用:

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

这似乎总是给check=false,但我认为这是因为t处于仅反射的上下文中,但SomeBaseType不是。{/ p>

我发现的解决方法是在仅反射上下文中加载基类的程序集,然后在该上下文中找到等效的基本类型。然后我们可以进行比较,其中两种类型都是仅反射的:

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。

答案 1 :(得分:0)

您不能将IsAssignableFrom与通过RefelectionOnlyLoad / ReflectionOnlyLoadFrom加载的程序集一起使用,因为IsAssignableFrom使用Type比较方法,例如IsSubclassOf。在内部,它确实通过内部的ImplementInterface方法调用GetInterfaces,但这就是它。

至于你的GetField调用,你传递了什么绑定标志?如果您没有通过,该领域是否公开?通常在设计上,大多数字段应该是私有/内部的,因此您需要确保将正确的绑定标志传递给GetField方法。

答案 2 :(得分:0)

我使用扩展方法来查看两个类型是否相等,只是比较AssemblyQualifiedName属性。它不是防弹的,但它绝对够好:

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

然后我可以调用这样的东西,例如:

bool equal = currType.ReflectionOnlyEquals(typeof(string));