如何使用反射来查找实现特定接口的属性



考虑这个例子:

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

你能完成if语句,用正确的代码替换something吗?

编辑:

我注意到我应该使用一个属性而不是字段来实现这一点,所以它应该是:

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

您可以查看属性的PropertyType,然后使用IsAssignableFrom,我认为这就是您想要的:

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

当然,如果你想让上面的代码工作,你需要向你的类添加一个属性;-)

另一种方法是从对象内部在接口上调用GetProperties(),而不是在对象本身上。

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

我喜欢将InterfaceName参数设置为Type,以避免在按字符串名称查找GetInterface()时出现任何拼写错误。

用法:

DisplayObjectInterface(Obj, typeof(InterFaceNameGoesHere));

EDIT:我刚刚注意到您的示例是一个集合,这对作为一个整体传递的集合不起作用。你必须单独传递每个项目。我很想删除,但这可能会帮助其他在谷歌上搜索相同问题的人寻找非收藏解决方案。

请注意,在您的示例中,在GetType().GetProperties ()中找不到catList。您应该使用GetType().GetFields ()

如果你试图确定属性是否定义为IEnumerable,你可以这样做:

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

如果您想知道是否可以将属性的值分配到IEnumerable<IAnimal>中,请执行以下操作:

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

如果属性类型不够具体(如object Animal{get;set;}),无法得到答案,则需要获取值来决定。你可以这样做:

object value = property.GetValue(this, null);
if (value is IEnumerable<IAnimal>)
{
   MessageBox.Show("animal list found");
}

相关内容

  • 没有找到相关文章