开发者

How can I use reflection to find the properties which implement a specific interface?

Consider this example:

public interface IAnimal
{
}

public cl开发者_运维技巧ass 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>();
        }
    }


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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜