简体   繁体   English

C#中如何判断一个属性是否为自定义类型?

[英]How do I determine if a property is a user-defined type in C#?

How do I determine if a property is a user-defined type?如何确定属性是否为用户定义类型? I tried to use IsClass as shown below but its value was true for String properties (and who knows what else).我尝试使用 IsClass,如下所示,但它的值对于 String 属性是正确的(谁知道还有什么)。

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

* Updated for more clarity * *更新更清晰*

I am trying to traverse a given type's definition and if the given type or any of its public properties are defined within the assembly, I am searching for an embedded JavaScript document.我试图遍历给定类型的定义,如果给定类型或其任何公共属性在程序集中定义,我正在搜索嵌入的 JavaScript 文档。 I just don't want to waste processing resources and time on native .NET types.我只是不想在原生 .NET 类型上浪费处理资源和时间。

@Bobson made a really good point: @Bobson提出了一个非常好的观点:

"...Unlike some other languages, C# does not make any actual distinction between "user-defined" and "standard" types." “......与其他一些语言不同,C#在”用户定义“和”标准“类型之间没有任何实际区别。”

Technically, @Bobson gave the answer; 从技术上讲,@ Bobson给出了答案; there is no distinguishing difference between a user-defined type and one defined in the .NET Framework or any other assembly for that matter. 用户定义的类型与.NET Framework中定义的类型或任何其他程序集之间没有区别。

However, I found a couple useful ways to determine if a type is user-defined. 但是,我找到了几种有用的方法来确定类型是否是用户定义的。

To search for all types defined within the given type's assembly, this works great: 要搜索给定类型程序集中定义的所有类型,这非常有用:

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

If the types can be defined in various assemblies, excluding the System namespace works in most cases: 如果可以在各种程序集中定义类型,则在大多数情况下不包括System名称空间:

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

If by "user-defined" you mean that it is not part of the standard assembly (mscorlib) then you can do something along the lines of this: 如果通过“用户定义”表示它不是标准程序集(mscorlib)的一部分,那么您可以按照以下方式执行某些操作:

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

However this will also consider types from external assemblies (aka: libraries) to be considered "user-defined". 但是,这也将考虑外部程序集(aka:libraries)中的类型被视为“用户定义”。 If you only want those in your current assembly then you can use 如果您只想要当前组件中的那些,那么您可以使用

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

I wrote a generic populator for unit testing that assigns predictable values to my objects and came across this kind of problem. 我为单元测试编写了一个通用的populator,它为我的对象分配了可预测的值,并遇到了这种问题。 In my case I wanted to know which of my properties were objects so that I could recursively populate those object properties, again with predictable values. 在我的情况下,我想知道我的哪些属性是对象,以便我可以递归地填充这些对象属性,同样具有可预测的值。

It seemed to me that introducing an interface implemented only by the classes that I was interested in traversing was the best way to do this. 在我看来,引入一个仅由我感兴趣的类遍历实现的接口是最好的方法。 You can then test to see if your property is an object of interest: 然后,您可以测试您的财产是否是您感兴趣的对象:

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

If by "user-defined" type you mean type that was declared in your executing assembly then you can obtain list of that types like in this sample c# console application: 如果通过“用户定义”类型表示在执行程序集中声明的类型,那么您可以获取这些类型的列表,如此示例c#console应用程序中所示:

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

UPDATE: 更新:

If you want to obtain list of types from all referenced assemblies: 如果要从所有引用的程序集中获取类型列表:

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() );
    }
}

Just be aware that Program type will also be in that list. 请注意, Program类型也将在该列表中。 Is this sufficient answer to your problem? 这是否足以解决您的问题?

Say your project is named "Foobar" and everything you make is under that namespace. 假设您的项目名为“Foobar”,您所做的一切都在该命名空间下。 You can test to see if you've written it by the following method: 您可以通过以下方法测试是否已编写它:

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

I struggled with this as well when creating a log when updating the database.在更新数据库时创建日志时,我也为此苦苦挣扎。 I did not want the classes to be shown in the log as they never == between data and dto.我不希望类显示在日志中,因为它们从不在数据和 dto 之间 ==。

foreach (PropertyType item in properties)
{
    if((item.PropertyType.IsClass && item.PropertyType.FullName.StartsWith("System.")) || !item.PropertyType.IsClass)
    {
       //...do stuff
    }
}

This allowed me to deal with strings and the likes which are flagged as classes.这使我能够处理标记为类的字符串等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Visual Studio 中将 Oracle 用户定义类型导出为 C# 类? - How do I export an Oracle User-defined Type as a C# class in Visual Studio? 在 C# 中,如何在编译时不知道类型的情况下访问用户定义类型的 static 属性? - In C#, how can you access a static property of a user-defined type without knowing the type at compiletime? C# Outlook 插件:如何以编程方式删除用户定义的属性? - C# Outlook Add-in: How can I delete a User-defined property programmatically? C#中的Visual Studio用户定义属性表宏 - Visual Studio user-defined property sheet macros in C# C#auto生成SQL“用户自定义表类型” - C# auto generate SQL “user-defined table type” C#:将用户定义的类型传递给Oracle存储过程 - C#: Pass a user-defined type to a Oracle stored procedure 如何从存储过程插入表(用户定义类型)并传递给C# - How insert into table(User-defined type) from Stored procedure and passing to c# 如何在C#中声明其类型是用户定义的实例 - How to declare an instance which its type is user-defined in C# 如何在PowerShell中的用户定义类中使用用户定义的结构? - How Do I Use a User-Defined Struct in a User-Defined Class in PowerShell? 在 C# 中如何使用和创建用户定义的委托? - How are user-defined delegates used and created in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM