How can I use reflection to find the properties wh

2019-04-04 12:03发布

Consider this example:

public interface IAnimal
{
}

public class Cat: IAnimal
{
}

public class DoStuff
{
    private Object catList = new List<Cat>();

    public void Go()
    {
        // I want to do this, but using reflection instead:
        if (catList is IEnumerable<IAnimal>)
            MessageBox.Show("animal list found");

        // now to try and do the above using reflection...
        PropertyInfo[] properties = this.GetType().GetProperties();
        foreach (PropertyInfo property in properties)
        {
            //... what do I do here?
            // if (*something*)
                MessageBox.Show("animal list found");
        }
    }
}

Can you complete the if statement, replacing something with the correct code?

EDIT:

I noticed that I should have used a property instead of a field for this to work, so it should be:

    public Object catList
    {
        get
        {
          return new List<Cat>();
        }
    }

3条回答
放我归山
2楼-- · 2019-04-04 12:10

Another way to do it is just call GetProperties() on the interface from within the object, opposed to on the object itself.

public static void DisplayObjectInterface(object source, Type InterfaceName)
{
    // Get the interface we are interested in
    var Interface = source.GetType().GetInterface(InterfaceName.Name);
    if (Interface != null)
    {
        // Get the properties from the interface, instead of our source.
        var propertyList = Interface.GetProperties();
        foreach (var property in propertyList)
            Debug.Log(InterfaceName.Name + " : " + property.Name + "Value " + property.GetValue(source, null));
    }
    else
        Debug.Log("Warning: Interface does not belong to object.");

}

I like to make InterfaceName parameter a Type to avoid any typo errors when looking up GetInterface() by string name.

Usage:

DisplayObjectInterface(Obj, typeof(InterFaceNameGoesHere));

EDIT: I just noticed that your example was a collection, this will not work on a collection passed as a whole. You would have to pass each item individually. I'm tempted to delete but this will probably help others that google this same question looking for a non-collection solution.

查看更多
Summer. ? 凉城
3楼-- · 2019-04-04 12:22

Please note that in your example, catList would not be found with GetType().GetProperties (). You would use GetType().GetFields () instead.

If you are trying to determine whether the property is defined as IEnumerable you can do this:

if (typeof(IEnumerable<IAnimal>) == property.PropertyType)
{
   MessageBox.Show("animal list found");
}

If you want to know if you can assign the value of the property into a IEnumerable<IAnimal>, do this:

if (typeof(IEnumerable<IAnimal>).IsAssignableFrom (property.PropertyType))
{
   MessageBox.Show("animal list found");
}

If the property type is not specific enough (like object Animal{get;set;}) to get your answer, you will need to get the value to decide. You can do this:

object value = property.GetValue(this, null);
if (value is IEnumerable<IAnimal>)
{
   MessageBox.Show("animal list found");
}
查看更多
你好瞎i
4楼-- · 2019-04-04 12:28

You can look at the properties' PropertyType, then use IsAssignableFrom, which I assume is what you want:

PropertyInfo[] properties = this.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
    if (typeof(IEnumerable<IAnimal>).IsAssignableFrom(property.PropertyType))
    {
        // Found a property that is an IEnumerable<IAnimal>
    }                           
}

Of course, you need to add a property to your class if you want the above code to work ;-)

查看更多
登录 后发表回答