C# - 如何检查 C# 中是不是存在命名空间、类或方法?
Posted
技术标签:
【中文标题】C# - 如何检查 C# 中是不是存在命名空间、类或方法?【英文标题】:C# - How to check if namespace, class or method exists in C#?C# - 如何检查 C# 中是否存在命名空间、类或方法? 【发布时间】:2012-01-19 22:32:12 【问题描述】:我有一个 C# 程序,如何在运行时检查命名空间、类或方法是否存在?另外,如何使用字符串形式的名字来实例化一个类?
伪代码:
string @namespace = "MyNameSpace";
string @class = "MyClass";
string method= "MyMEthod";
var y = IsNamespaceExists(namespace);
var x = IsClassExists(@class)? new @class : null; //Check if exists, instantiate if so.
var z = x.IsMethodExists(method);
【问题讨论】:
请记住将最合适的回复标记为答案。 【参考方案1】:您可以使用Type.GetType(string) 到reflect 一个类型。如果找不到类型,GetType
将返回 null。如果该类型存在,则可以从返回的Type
中使用GetMethod
、GetField
、GetProperty
等来检查您感兴趣的成员是否存在。
Update 你的例子:
string @namespace = "MyNameSpace";
string @class = "MyClass";
string method= "MyMEthod";
var myClassType = Type.GetType(String.format("0.1", @namespace, @class));
object instance = myClassType == null ? null : Activator.CreateInstance(myClassType); //Check if exists, instantiate if so.
var myMethodExists = myClassType.GetMethod(method) != null;
Console.WriteLine(myClassType); // MyNameSpace.MyClass
Console.WriteLine(myMethodExists); // True
这是最有效和首选的方法,假设类型在 当前正在执行的程序集中,在 mscorlib 中(不确定 .NET Core 对此有何影响,也许是 System.Runtime
?),或者你有一个assembly-qualified name 类型。如果您传递给GetType
的字符串参数不满足这三个要求,GetType
将返回 null(假设没有其他类型不小心与这些要求重叠,哎呀)。
如果您没有具有程序集限定名称,则您需要修正您的方法以便执行或执行搜索,后者可能会慢得多。
如果我们假设您确实想在所有加载的程序集中搜索类型,您可以执行以下操作(使用 LINQ):
var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Name == className
select type);
当然,可能还不止这些,您需要反映可能尚未加载的引用程序集,等等。
至于确定命名空间,反射不会明确地导出它们。相反,您必须执行以下操作:
var namespaceFound = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == namespace
select type).Any()
把它们放在一起,你会得到类似的东西:
var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Name == className && type.GetMethods().Any(m => m.Name == methodName)
select type).FirstOrDefault();
if (type == null) throw new InvalidOperationException("Valid type not found.");
object instance = Activator.CreateInstance(type);
【讨论】:
您将如何确定您的示例中是否存在命名空间? 更新了我的答案。检查第二个代码示例。我们枚举每个加载的程序集,以及每个程序集中的每种类型,并查找具有所需命名空间名称的任何类型。 如果要检查命名空间是否有效、类名是否有效以及该类是否有方法,则可以通过第三个代码示例一键完成所有操作。只需将 where type.Name == className 更改为where type.FullName == string.Format("0.1", namespace, className) && type.GetMethods().Any(m => m.Name == methodName)
即可。另外,我在这些示例中犯了一个错误,因为省略了声明的select
部分。已更正。
+1 很好的例子。我什至没有意识到有一个 Type.Namespace 属性...
您可以使用嵌套的foreach
循环来执行此操作;我只是选择了 LINQ,因为它更容易。如果您愿意,我可以提供这样的示例。【参考方案2】:
您可以使用Type.GetType(String) 方法从字符串中解析Type。 例如:
Type myType = Type.GetType("MyNamespace.MyClass");
然后您可以使用此 Type 实例通过调用 GetMethod(String) 方法来检查该类型上是否存在方法。 例如:
MethodInfo myMethod = myType.GetMethod("MyMethod");
如果没有找到给定名称的类型或方法,GetType 和 GetMethod 都返回 null
,因此您可以通过检查您的方法调用是否返回 null 来检查您的类型/方法是否存在。
最后,您可以使用Activator.CreateInstance(Type) 实例化您的类型 例如:
object instance = Activator.CreateInstance(myType);
【讨论】:
这是一个比上面标记为正确的答案更快、更简洁的答案。在每个组件中旋转每种类型都非常缓慢。如果包含所有系统程序集,则可能是 10,000 次迭代循环。 这就是我所追求的,简短而简单。【参考方案3】:一个字:Reflection。除了命名空间,您必须从类型名称中解析出来。
编辑: 强调一下 - 对于命名空间,您必须使用 Type.Namespace 属性来确定每个类属于哪个命名空间。 (有关更多信息,请参阅HackedByChinese response)。
【讨论】:
不幸的是,反射 URL 已关闭 修复了损坏的反射链接。以上是关于C# - 如何检查 C# 中是不是存在命名空间、类或方法?的主要内容,如果未能解决你的问题,请参考以下文章
当存在同名的子命名空间时,如何在 c# 中引用完整的命名空间? [复制]