【问题标题】:How can we differentiate between SDK class objects and custom class objects?我们如何区分 SDK 类对象和自定义类对象?
【发布时间】:2010-04-13 06:22:51
【问题描述】:

要了解我的要求,请考虑这些类 -

class A { }

class B {
    String m_sName;
    public String Name {
        get { return m_sName; }
        set { m_sName = value; }
    }

    int m_iVal;
    public int Val {
        get { return m_iVal; }
        set { m_iVal = value; }
    }

    A m_objA;
    public A AObject {
        get { return m_objA; }
        set { m_objA = value; }
    }
}

现在,我需要识别传递给函数的对象的类

void MyFunc(object obj) {
    Type type = obj.GetType();

    foreach (PropertyInfo pi in type.GetProperties()) {
        if (pi.PropertyType.IsClass) { //I need objects only

            if (!type.IsGenericType && type.FullName.ToLower() == "system.string") {
                object _obj = pi.GetValue(obj, null);
                //do something
            }
        }
    }
}

我不喜欢这段代码-

    if (!type.IsGenericType && type.FullName.ToLower() == "system.string") {

因为我必须过滤掉 System.Int16、System.Int32、System.Boolean 等类。

是否有一种优雅的方法可以让我确定对象是否属于我定义的类而不是系统提供的基本类?

【问题讨论】:

    标签: c# reflection c#-2.0


    【解决方案1】:

    一种可能的方法是使用Type.Assembly 属性并过滤掉任何未在您的程序集中声明的任何内容。这种方法的缺点是您需要在执行时了解所有程序集,这在某些(不常见的)场景中可能很难。

    【讨论】:

    • 是的。当您制作通用/组件类时,它会使工作变得更加困难。最终用户可能有任何带有或不带有属性的类。很难过滤掉。
    【解决方案2】:

    没有真正可靠的方法。想到的一件事是查看定义给定类型的程序集:type.Assembly 并将其与 已知 程序集列表进行比较。

    【讨论】:

      【解决方案3】:

      据我所知,没有办法知道一个类是来自 BCL 还是用户定义的类,但也许你可以从一些众所周知的框架 dll 中缓存一些程序集信息。

      您可以循环浏览 mscorlib.dll 中的所有类并将它们放入一个列表中,然后根据该列表检查您的类名。

      【讨论】:

        【解决方案4】:

        您可以查看类型的Assembly 属性上AssemblyQualifiedName 的PublicKeyToken 属性。但是您必须收集框架为不同版本的运行时使用的不同标记,并与这些标记进行比较。

        【讨论】:

          【解决方案5】:

          如果有可能,最简单的方法是使用可以检查的属性标记自己的类(而不是检查泛型和类型的名称)。

          【讨论】:

          • 我正在制作一个通用/组件类。因此,我不能真正依赖属性,因为如果您意识到,上述函数的行为是探索传递给它的对象。最终用户可能有任何带或不带属性的类,他们仍然可以使用 MyFunc。很难过滤掉。
          • 我明白,我想。您正在寻找的是类型上的属性,“bool IsBuiltIn”或类似的东西。对吗?
          • 如果有这样的属性,是的。恐怕,我还没有找到这样的东西。
          • 据我所知,没有这样的属性。如果您可以接受不太理想的解决方案,您可以枚举所有导出的 mscorlib 类型并检查列表;例如使用 typeof(string).GetType().Assembly.GetExportedTypes()。哎呀。刚刚看到 Jorge 在下面提出了相同的解决方案。
          【解决方案6】:

          我有一个便宜又快速的解决方案,可能会奏效:

          if( type.IsClass && ! type.IsSealed )
          

          System.String 对象是一个类,但它也被密封以防止继承。只要您没有在代码中使用密封类,它就可以工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-01
            相关资源
            最近更新 更多