views:

72

answers:

5

To give an idea of my requirement, consider these classes -

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

Now, I need to identify the classes of the objects passed to a function

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

I don't like this piece of code -

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

because then i have to filter out classes like, System.Int16, System.Int32, System.Boolean and so on.

Is there an elegant way through which I can find out if the object is of a class defined by me and not of system provided basic classes?

A: 

There isn't really a reliable way. One thing that comes to mind is to look at the assembly the given type is defined: type.Assembly and compare this against a list of known assemblies.

Darin Dimitrov
A: 

As far as I Know there is no way to know if a class is from the BCL or is a user defined class but maybe you could just cache some assembly information from some well known framework dll.

You could cycle through all the classes in mscorlib.dll and put them into a List and then checking your class names against that list.

Jorge Córdoba
A: 

One possible approach would be to use the Type.Assembly property and filter out anything that is not declared in one of your assemblies. The drawback of this approach is that you need to know all your assemblies at execution time, which might be hard in certain (not as common) scenarios.

Franci Penov
True. It makes the job harder when you are making a generic/component class.The end user might have any class written with or without attributes. It will be difficult to filter out.
Nayan
A: 

You could have a look at the PublicKeyToken attribute of the AssemblyQualifiedName on the type's Assembly property. But you would have to gather up the different tokens used by the framework for different versions of the runtime and compare to those.

Mikael Svenson
A: 

The easiest way, if you have the possibility, is to mark your own classes with an attribute that you can check for (instead of checking for generics and the name of the type).

Christoffer
I'm making a generic/component class. So, I cannot really rely on attribute because the behavior of the above function, if you realize, is to explore the object passed to it.The end user might have any class written with or without attributes, and still they can use MyFunc. It will be difficult to filter out.
Nayan
I understand, I think. What you are looking for is a property on the Type, "bool IsBuiltIn", or something similar. Correct?
Christoffer
If there is any such property, yes. I am afraid, I haven't found any such thing.
Nayan
To the best of my knowledge, there is no such property. If you could live with a less-than-optimal solution, you could enumerate all exported types of mscorlib and check against the list; use for example typeof(string).GetType().Assembly.GetExportedTypes(). Oops. Just saw that Jorge suggested the same solution below.
Christoffer