如何确定属性是否是C#中的用户定义类型?

如何确定属性是否是用户定义的类型? 我尝试使用IsClass,如下所示,但它的值对于String属性是真的(谁知道还有什么)。

foreach (var property in type.GetProperties()) { if (property.PropertyType.IsClass) { // do something with property } } 

*更新以获得更清晰*

我试图遍历给定类型的定义,如果在程序集中定义了给定类型或其任何公共属性,我正在搜索嵌入式JavaScript文档。 我只是不想在本机.NET类型上浪费处理资源和时间。

如果通过“用户定义”表示它不是标准程序集(mscorlib)的一部分,那么您可以按照以下方式执行某些操作:

 if(typeof(SomeType).Assembly.GetName().Name != "mscorlib") { // user-defined! } 

但是,这也将考虑外部程序集(aka:libraries)中的类型被视为“用户定义”。 如果您只想要当前组件中的那些,那么您可以使用

 typeof(SomeType).Assembly == Assembly.GetExecutingAssembly() 

@Bobson提出了一个非常好的观点:

“……与其他一些语言不同,C#在”用户定义“和”标准“类型之间没有任何实际区别。”

从技术上讲,@ Bobson给出了答案; 用户定义的类型与.NET Framework中定义的类型或任何其他程序集之间没有区别。

但是,我找到了几种有用的方法来确定类型是否是用户定义的。

要搜索给定类型的程序集中定义的所有类型,这非常有用:

 foreach (var property in type.GetProperties()) { if (property.PropertyType.IsClass && property.PropertyType.Assembly.FullName == type.Assembly.FullName) { // do something with property } } 

如果可以在各种程序集中定义类型,则在大多数情况下不包括System名称空间:

 foreach (var property in type.GetProperties()) { if (property.PropertyType.IsClass && !property.PropertyType.FullName.StartsWith("System.")) { // do something with property } } 

我为unit testing编写了一个通用的populator,它为我的对象分配了可预测的值,并遇到了这种问题。 在我的情况下,我想知道我的哪些属性是对象,以便我可以递归地填充这些对象属性,同样具有可预测的值。

在我看来,引入一个仅由我感兴趣的类遍历实现的接口是最好的方法。 然后,您可以测试您的财产是否是您感兴趣的对象:

  public static bool IsMyInterface(this Type propertyType) { return propertyType.GetInterface("MyInterfaceName") != null; } 

如果通过“用户定义”类型表示在执行程序集中声明的类型,那么您可以获取这些类型的列表,如此示例c#console应用程序中所示:

 class Program { static void Main( string[] args ) { var currentAssembly = Assembly.GetExecutingAssembly(); var localTypes = currentAssembly.GetTypes(); } } 

更新:

如果要从所有引用的程序集中获取类型列表:

 class Program { static void Main( string[] args ) { var currentAssembly = Assembly.GetExecutingAssembly(); var referencedAssemblies = currentAssembly.GetReferencedAssemblies(); var typesFromReferencedAssemblies = referencedAssemblies.Select( assemblyName => Assembly.ReflectionOnlyLoad( assemblyName.FullName ) ).SelectMany( assembly => assembly.GetTypes() ); } } 

请注意, Program类型也将在该列表中。 这是否足以解决您的问题?

假设您的项目名为“Foobar”,您所做的一切都在该命名空间下。 您可以通过以下方法测试是否已编写它:

 typeof(SomeType).Namespace.Contains("Foobar");