使用字符串获取程序集

Get assembly using string

程序使用反射获取有关 class 的信息,例如 method/feilds/properties 名称 return 类型参数。现在我让用户输入名称并查看数据。使用 .Net 库或我自己的程序集时工作正常。但是当我要求它从我制作的不同程序集中查找内容时,它就是找不到。这是代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace CSharpVenkat
{

    class Program
    {

        static void DataFinder()
        {
            try
            {
                //Using bool as I didnt want to make a nested for loop

                bool consoleColorSet = false;

                for (;;)
                {

                    if (consoleColorSet == false)
                    {
                        Console.BackgroundColor = ConsoleColor.Black;

                        Console.Clear();

                        consoleColorSet = true;
                    }

                    Console.Write("Class: ");
                    string s = Console.ReadLine();

                    Console.WriteLine();

                    Type t = Type.GetType(s) as Type;

                    if (t != null)
                    {
                        //Methods

                        MethodInfo[] methods = t.GetMethods();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Methods of class \"" + t.FullName + "\"");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine();

                        if (methods.Length <= 0)
                        {

                            Console.WriteLine("None!");

                        }

                        foreach (MethodInfo method in methods)
                        {

                            Console.WriteLine(method.ToString());

                        }

                        Console.WriteLine();
                        Console.WriteLine();

                        //Constructors

                        ConstructorInfo[] constructors = t.GetConstructors();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Constructor of class \"" + t.FullName + "\"");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine();

                        if (constructors.Length <= 0)
                        {

                            Console.WriteLine("None!");

                        }

                        foreach (ConstructorInfo constructor in constructors)
                        {

                            Console.WriteLine(constructor.Name + " " + constructor.ToString());

                        }

                        Console.WriteLine();
                        Console.WriteLine();

                        //Fields

                        FieldInfo[] fields = t.GetFields();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Fields of class \"" + t.FullName + "\"");
                        Console.ForegroundColor = ConsoleColor.White;

                        Console.WriteLine();

                        if (fields.Length <= 0)
                        {

                            Console.WriteLine("None!");

                        }

                        foreach (FieldInfo field in fields)
                        {

                            Console.WriteLine(field.FieldType.Name + " " + field.Name);

                        }

                        Console.WriteLine();
                        Console.WriteLine();

                        //Properties

                        PropertyInfo[] properties = t.GetProperties();

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Properties of class \"" + t.FullName + "\"");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine();

                        if (properties.Length <= 0)
                        {

                            Console.WriteLine("None!");

                        }

                        foreach (PropertyInfo property in properties)
                        {

                            Console.WriteLine(property.PropertyType.Name + " " + property.Name);

                        }


                        break;
                    }

                    else
                    {

                        Console.WriteLine("Invalid ! Please check your namespace and class name!");
                        Console.WriteLine();

                    }
                }
            }

            //Really Incase something goes wrong, I dont know anything that could go wrong here still!

            catch (Exception e)
            {

                Console.WriteLine("Programm stopped responding! due to  error", e.GetType().Name);

            }


        }

        //Main method

        static void Main(string[] args)                    
        {

            DataFinder();


            Console.ReadKey();
        }


    }
}

现在我知道我可以通过执行

来获得我正在尝试执行的 class 的程序集
Assembly a = Assembly.GetAssembly(typeof(ClassName));
Type t = a.GetType(s); //s is the userput

但问题是我想让控制台用户执行此操作,而不是我写 class 名称。我也不能在 typeof 中传递一个字符串。问题是这样的:如果我想要用户输入的 "Type",我需要先获取程序集,但要获取程序集,我需要获取 "Type"。我该如何解决这个问题。

给定一个包含类型名称的字符串(例如 My.Namespace.MyTypeMyType),没有内置方法将其解析为 AssemblyType 实例。在我看来,您有 2 个选择:

  1. 如果包含该类型的程序集位于您知道的位置(例如,可能所有程序集都在与主 "entry point" 程序集相同的目录中),您可以手动加载程序集并尝试找到类型。
  2. 如果程序集不在众所周知的位置,您将不得不要求用户输入程序集名称或程序集的完整路径。参见 Type.GetType or Assembly.Load or Assembly.LoadFrom

如果输入的是部分名称(例如 ListBox 而不是 System.Windows.Controls.ListBox),您可以使用:

var types = AppDomain.CurrentDomain.GetAssemblies()
    .Select(x => Assembly.Load(x.FullName))
    .SelectMany(x => x.GetExportedTypes())
    .Where(x => x.Name == s)
    .ToList();

注意:有时您可能会得到不止 1 个结果。

如果你输入的是全名,你可以这样使用:

var type = AppDomain.CurrentDomain.GetAssemblies()
    .Select(x => Assembly.Load(x.FullName))
    .Select(x => x.GetType(s))
    .FirstOrDefault(x => x != null);