Reflection GetProperties should exclude unwanted children properties on certain datatype

StackOverflow https://stackoverflow.com/questions/21546400

  •  06-10-2022
  •  | 
  •  

Question

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

Était-ce utile?

La solution 3

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.

Autres conseils

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

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.

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top