0

Let say I have classes hierarchy like

public class A
{
    public int AMember { get; set; }
}

public class B
{
    public int BMember { get; set; }
    public virtual A AasMember { get; set; }
}

public static class OrderByUtility
{
    public static bool PropertyExists<T>(string propertyName)
    {
        return typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase |
                     BindingFlags.Public) != null;
    }
}

From main class whenever I use this Utility

OrderByUtility.PropertyExists BClass>("BMember");

This works fine and returns TRUE. But whenever I use

OrderByUtility.PropertyExists BClass> ("AMember"); returns False

I want same PropertyExist function work for all Composed Object. Please suggest resolving this issue. Thanks

Farhana Naaz Ansari
  • 7,524
  • 26
  • 65
  • 105
  • Possible duplicate of [How do you get the all properties of a class and its base classes (up the hierarchy) with Reflection? (C#)](https://stackoverflow.com/questions/245055/how-do-you-get-the-all-properties-of-a-class-and-its-base-classes-up-the-hierar) – Evan Trimboli Apr 27 '18 at 05:58
  • Inheritance is separate concept in my case its Composition for getting class properties. – Zeeshan Maqsood Apr 27 '18 at 06:23

1 Answers1

0

Here is a really naive implementation of it. You could make it recursive to keep checking nested types. It also keeps a cache so it doesn't do the expensive processing on each lookup.

public class A
{
    public int AMember { get; set; }
}

public class B
{
    public int BMember { get; set; }
    public virtual A AasMember { get; set; }
}

public static class OrderByUtility
{
    private static readonly Dictionary<Type, Dictionary<string, bool>> Seen =
        new Dictionary<Type, Dictionary<string, bool>>();

    public static bool PropertyExists<T>(string propertyName)
    {
        var type = typeof(T);

        if (!Seen.TryGetValue(type, out var props))
        {
            props = new Dictionary<string, bool>();
            Seen[type] = props;
        }

        if (props.ContainsKey(propertyName))
        {
            return props[propertyName];
        }

        var prop = GetPropertyByName(type, propertyName);
        if (prop == null)
        {
            foreach (var p in type.GetProperties())
            {
                var propType = p.PropertyType;
                if (!propType.IsClass && !propType.IsInterface) continue;

                prop = GetPropertyByName(propType, propertyName);
                if (prop != null)
                {
                    break;
                }
            }
        }

        props[propertyName] = prop != null;
        return props[propertyName];
    }

    private static PropertyInfo GetPropertyByName(Type t, string name)
    {
        return t.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
    }
}

Usage:

bool exists = OrderByUtility.PropertyExists<B>("AMember");

Evan Trimboli
  • 29,900
  • 6
  • 45
  • 66