如何识别List <t>是否是实现特定接口的Ts列表</t>

时间:2014-09-07 12:16:40

标签: c# list interface

好的,我有一个包含多个List类型属性的类。

有些列表只是简单类型,例如stringint等。 但有些是自定义类型的列表,如功能,预告片,艺术品等。

public class Movie : IMedia
{
   public List<Feature> Features;
   public List<Artwork> Artwork;
   public List<string> Genres;
}

所有自定义类型(以及Movie类本身)都实现了接口IMedia

使用反射我想遍历Movie属性并对List<IMedia>类型的那些做一些事情 - 但这就是问题所在;因为显然我不能只使用is List<IMedia>同时想要将属性指定为List<Feature>这样的特定类型。

你们怎么建议我去识别这些类型?

扩展List<T>本身或完全不同的东西?

3 个答案:

答案 0 :(得分:3)

获取第一个通用参数的类型:

var lst = new List<MyClass>();
var t1 = lst.GetType().GenericTypeArguments[0];

检查是否可以将其强制转换为界面:

bool b = typeof(IInterface).IsAssignableFrom(t1);

另一种方法可能是:

var castedLst = lst.OfType<IInterface>().ToList();
bool b = castedLst.Count == lst.Count; // all items were casted successfully

答案 1 :(得分:2)

假设您实际上正在使用属性(这是问题中提到的)而不是私有字段(这是您问题中的类正在使用的) ,你可以这样做:

var movie = new Movie() { ... };

foreach (var prop in typeof(Movie).GetProperties())
{
    if (prop.PropertyType.IsGenericType && 
        prop.PropertyType.GetGenericTypeDefinition() == typeof (List<>))
    {
        /* Get the generic type parameter of the List<> we're working with: */
        Type genericArg = prop.PropertyType.GetGenericArguments()[0];

        /* If this is a List of something derived from IMedia: */
        if (typeof(IMedia).IsAssignableFrom(genericArg))
        {
            var enumerable = (IEnumerable)prop.GetValue(movie);

            List<IMedia> media = 
                enumerable != null ? 
                enumerable.Cast<IMedia>().ToList() : null;

            // where DoSomething takes a List<IMedia>
            DoSomething(media);
        }
    }
}

答案 2 :(得分:-2)

如果我理解你,你必须做这样的事情:

Type paramType = typeof(T);
if(paramType is IMedia) { /*do smt*/ }