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 中使用GetMethodGetFieldGetProperty 等来检查您感兴趣的成员是否存在。

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#如何获取某一命名空间下的所有的类的信息(方法以及参数)

如何检查在 C# 的全局类中找到的数组中是不是存在对象

当存在同名的子命名空间时,如何在 c# 中引用完整的命名空间? [复制]

c#里一个文件夹下可以添加多个命名空间和类名相同的类么

命名空间“系统”中不存在类型或命名空间名称“事务”(您是不是缺少程序集引用?) - C# ASP.NET

最佳实践:C# 扩展方法命名空间和推广扩展方法