Как мы можем различать объекты класса SDK и объекты пользовательских классов? - PullRequest
0 голосов
/ 13 апреля 2010

Чтобы дать представление о моем требовании, рассмотрим эти классы -

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 и т. Д.

Есть ли изящный способ, с помощью которого я могу узнать, принадлежит ли объект определенному мной классу, а не классу, предоставленному системой?

Ответы [ 6 ]

1 голос
/ 13 апреля 2010

Один из возможных подходов - использовать свойство Type.Assembly и отфильтровывать все, что не объявлено в одной из ваших сборок. Недостаток этого подхода заключается в том, что вам нужно знать все свои сборки во время выполнения, что может быть сложно в некоторых (не так часто встречающихся) сценариях.

1 голос
/ 13 апреля 2010

На самом деле нет надежного способа. Одна вещь, которая приходит на ум, - это посмотреть на сборку, для которой определен данный тип: type.Assembly и сравнить ее со списком известных сборок.

0 голосов
/ 05 июля 2012

У меня есть дешевое и быстрое решение, которое может работать:

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

Объект System.String является классом, но он также защищен от наследования. Это работает до тех пор, пока вы не используете запечатанные классы в своем коде.

0 голосов
/ 13 апреля 2010

Самый простой способ, если у вас есть возможность, это пометить свои собственные классы атрибутом, который вы можете проверить (вместо проверки на дженерики и имя типа).

0 голосов
/ 13 апреля 2010

Вы можете взглянуть на атрибут PublicKeyToken AssemblyQualifiedName в свойстве Assembly типа. Но вам придется собрать разные токены, используемые платформой для разных версий среды выполнения, и сравнить с ними.

0 голосов
/ 13 апреля 2010

Насколько я знаю, нет никакого способа узнать, является ли класс из BCL или пользовательским классом, но, возможно, вы могли бы просто кэшировать некоторую информацию о сборке из некоторого хорошо известного фреймворка dll.

Вы можете перебрать все классы в mscorlib.dll и поместить их в список, а затем проверить имена своих классов по этому списку.

...