使用字符串获取程序集
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.MyType
或 MyType
),没有内置方法将其解析为 Assembly
或 Type
实例。在我看来,您有 2 个选择:
- 如果包含该类型的程序集位于您知道的位置(例如,可能所有程序集都在与主 "entry point" 程序集相同的目录中),您可以手动加载程序集并尝试找到类型。
- 如果程序集不在众所周知的位置,您将不得不要求用户输入程序集名称或程序集的完整路径。参见
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);
程序使用反射获取有关 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.MyType
或 MyType
),没有内置方法将其解析为 Assembly
或 Type
实例。在我看来,您有 2 个选择:
- 如果包含该类型的程序集位于您知道的位置(例如,可能所有程序集都在与主 "entry point" 程序集相同的目录中),您可以手动加载程序集并尝试找到类型。
- 如果程序集不在众所周知的位置,您将不得不要求用户输入程序集名称或程序集的完整路径。参见
Type.GetType
orAssembly.Load
orAssembly.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);