无法在仅反射上下文

时间:2017-09-17 21:00:26

标签: c# .net system.reflection

以下代码正确显示了方法的名称:

static void Main(string[] args)
{
    try
    {
        Assembly assembly = Assembly.Load("ClassLibrary1");
        foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
        {
            Assembly.Load(referencedAssembly.Name);
        }
        Type bl1Type = assembly.GetType("ClassLibrary1.Bl1");
        var types = new[] {typeof(MyEnum) };
        var method = bl1Type.GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public, Type.DefaultBinder, types, null);
        Console.WriteLine(method == null ? "Method was null" : $"Found {method.Name}");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

但是,如果我尝试在仅反射上下文中解析Method1以提高性能并使用Assembly.Load("ClassLibrary1");将调用更改为Assembly.ReflectionOnlyLoad("ClassLibrary1");,则method始终为null且无法解析。关于如何在仅反射上下文中解决方法的任何想法?

2 个答案:

答案 0 :(得分:2)

如果您尝试以下操作,您将看到您的方法在列表中找到

var methods = bl1Type.GetMethods(BindingFlags.Instance | BindingFlags.Public);

此外,如果您搜索接受字符串参数的方法,它也将起作用

var types = new[] {typeof(string)};

我认为它被MyEnum弄糊涂了 如果从第二个dll加载MyEnum,它将起作用

Assembly assembly2 = Assembly.ReflectionOnlyLoad("ClassLibrary2");
Type bl2Type = assembly2.GetType("ClassLibrary2.MyEnum");
var types = new[] { bl2Type };

完整代码

using System;
using System.Linq;
using System.Reflection;

namespace ReflectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.ReflectionOnlyLoad("ClassLibrary1");
            Type bl1Type = assembly.GetType("ClassLibrary1.Bl1");
            var types = new[] { Assembly.ReflectionOnlyLoad(assembly.GetReferencedAssemblies().Single(a => a.Name == "ClassLibrary2").Name).GetType("ClassLibrary2.MyEnum") };
            //var types = new[] {typeof(MyEnum)}; //doesn't work
            var method = bl1Type.GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public, Type.DefaultBinder, types, null);
            Console.WriteLine(method == null ? "Method was null" : $"Found {method.Name}");
            Console.ReadLine();
        }
    }
}

所以,你的初始代码不起作用,因为它试图找到一个使用不同的" MyEnum" (当然它并不存在)

答案 1 :(得分:1)

ReflectionOnly上下文是来自常规加载器上下文的独立加载器上下文。它加载了自己的程序集和类型的副本,mscorlib中的系统类型与常规加载器上下文共享。

此外,将程序集加载到ReflectionOnly上下文中通常没有性能优势。 ReflectionOnly上下文使用与常规程序集完全相同的加载机制,除了尝试从它们执行任何代码被阻止并且一些健全性检查被禁止(https://blogs.msdn.microsoft.com/junfeng/2004/08/24/reflection-only-assembly-loading/描述详细信息)。