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

本文关键字:用户 定义 类型 是否是 属性 何确定 一个 | 更新日期: 2023-09-27 18:04:26

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

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

*更新更清晰*

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

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

@Bobson说得很好:

"……不像其他语言,c#不做任何实际的"用户定义"answers"标准"类型之间的区别。"

严格来说,@Bobson给出了答案;用户定义的类型与。net框架或任何其他程序集中定义的类型之间没有明显的区别。

但是,我发现了一些有用的方法来确定类型是否是用户定义的。

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

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
    }
}

如果"用户定义"的意思是它不是标准程序集(mscorlib)的一部分,那么您可以按照以下行做一些事情:

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

然而,这也会认为来自外部程序集(又名:库)的类型是"用户定义的"。如果你只想要当前程序集中的那些,那么你可以使用

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

我在更新数据库时创建日志时也遇到过这个问题。我不希望在日志中显示类,因为它们从不在data和dto之间==。

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

这允许我处理字符串和类似的标记为类。

我为单元测试编写了一个通用的填充器,它将可预测的值分配给我的对象,并遇到了这种问题。在我的例子中,我想知道我的哪些属性是对象,这样我就可以递归地填充这些对象属性,同样使用可预测的值。

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

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

假设你的项目命名为"Foobar",你所做的一切都在这个命名空间下。您可以通过以下方法进行测试,看看是否已经编写了该代码:

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

如果"用户定义"类型是指在执行程序集中声明的类型,那么您可以获得该类型的列表,如下面的示例c#控制台应用程序:

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类型也将在该列表中。这足以回答你的问题吗?