1

Surely I am missing the obvious.I am building an internal application and I am reflecting on some of our internal dlls and displaying them in a tree view

Treeview is loaded on demand and for each property when expanded I get the children if any. When children are datetime,string,decimal etc.. I then are expanded once again I should not be getting all the inner properties of a string or datetime and so on . It should not return anything.I have tried few bindingFlags but we no success.

I am using the following method but it's not good enough.

  public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!t.IsPrimitive
            || t != typeof (System.Decimal)
            || t != typeof (System.String)
              || t != typeof(System.DateTime)
            || t != typeof (System.DateTime?))
        {

            return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
        }
        return new PropertyInfo[0];
    }

What I want is that when getting Properties it should exclude all the inner properties that a not relevant.

EG Customer has order and order has OrderedDate.When using the treeview I click on customer and I get order click on order and I get OrderDate when clicking orderdate I should have no properties.I get "HasValue and value" and expand value and get all the datetime stuff.

Same when a property is a string I should not see Chars and Length.

Any suggestions

user9969
  • 15,632
  • 39
  • 107
  • 175

4 Answers4

1

you should manually check for primitive types and return an empty array. you can check that with the answer to the wuestion here How To Test if Type is Primitive

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
    // Is Primitive, or Decimal, or String
}

so basically you can do

public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
    {
        return //empty array
    }
        return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
    }

-Update

public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!t.IsPrimitive
            || t != typeof (System.Decimal)
            || t != typeof (System.String)
            || t != typeof(System.DateTime)
            || t != typeof (System.DateTime?))
        {

            return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
        }
        else
        return new PropertyInfo[0];
    }
Community
  • 1
  • 1
Parv Sharma
  • 12,581
  • 4
  • 48
  • 80
1

Before expanding you should check Type.FullName property and do not expand if type it is not in your namespaces.

To elaborate a little, the following code from MSDN illustrates what FullName does:

Type t = typeof(Array);
Console.WriteLine("The full name of the Array type is {0}.", t.FullName);

/* This example produces the following output:

The full name of the Array type is System.Array.
*/

You can test for example if FullName starts with "System." or "Microsoft." and do not expand those properties.

Bogdan
  • 484
  • 2
  • 7
0

May be:

    public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!typeof (MyBasePropertyClass).IsAssignableFrom(t))
            return new PropertyInfo[0];

        return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name)
                .ToArray();
    }

where MyBasePropertyClass is a base class for your entities.

neodim
  • 468
  • 4
  • 15
0
if (!t.IsPrimitive
    || t != typeof (System.Decimal)
    || t != typeof (System.String)
    || t != typeof(System.DateTime)
    || t != typeof (System.DateTime?))

should be

if (!t.IsPrimitive
    && t != typeof (System.Decimal)
    && t != typeof (System.String)
    && t != typeof(System.DateTime)
    && t != typeof (System.DateTime?))

As is, your conditional will always evaluate to true since all types are either not System.String or not System.Decimal and you are combining them with the OR operator.

Derek J S
  • 166
  • 3
  • hi,That is seeems to work! how do you detect nullable bool as bool? does not seem to be detected. – user9969 Feb 04 '14 at 16:56
  • 1
    @user231465 If you are getting the parameter Type t from a call to GetType(), you shouldn't need to detect nullable bool (calling GetType() on a bool? should return typeof(bool)). See http://msdn.microsoft.com/en-us/library/ms366789.aspx. If this solves your problem, please accept the answer. – Derek J S Feb 04 '14 at 17:26
  • @DerekJS Begging for fame? :) – Bogdan Feb 04 '14 at 18:45
  • 1
    @Bogdan I just got enough to comment yesterday, so for the moment, yeah. – Derek J S Feb 04 '14 at 19:58