好的,我有一个包含多个List
类型属性的类。
有些列表只是简单类型,例如string
,int
等。
但有些是自定义类型的列表,如功能,预告片,艺术品等。
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>
本身或完全不同的东西?
答案 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*/ }