【问题标题】:How to identify whether List<T> is a list of Ts that implement a specific interface如何识别 List<T> 是否是实现特定接口的 T 列表
【发布时间】:2014-10-31 20:02:24
【问题描述】:

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

有些列表只是简单的类型,如stringint 等。 但有些是自定义类型的列表,例如 Feature、Trailer、Artwork 等。

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

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

使用反射我想遍历 Movie 属性并对 List&lt;IMedia&gt; 类型的属性做一些事情 - 但问题就在这里;因为显然我不能只使用is List&lt;IMedia&gt;,同时还想将属性指定为特定类型,例如List&lt;Feature&gt;

你们建议我如何识别这些类型?

扩展List&lt;T&gt; 本身还是完全不同的东西?

【问题讨论】:

  • 你应该展示你的代码。没有您的代码,我们不可能知道出了什么问题。
  • 您要识别列表的类型还是列表中元素的类型?
  • 听起来像是扩展类的教科书用例,出于好奇,尽管 is List&lt;T&gt;.GetType() == TypeOf(List&lt;T&gt;) 应该可以工作,除非您明确重铸该类,并且如果这些类如此熟悉且仅在name 为什么区分它们的对象可以作为对象存储在类中?
  • 我不建议您在简单的 BL 案例中使用反射。这似乎是一种过度概括。 IE。实现在某些条件下返回 IList 的公共方法。

标签: c# list interface


【解决方案1】:

假设您实际上是在使用 properties(这是问题中提到的)而不是 private fields(这是您问题中的类正在使用的) ,你可以这样做:

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

【讨论】:

  • 这正是我想要实现的。谢谢@Andrew Whitaker
  • @Marle1:没问题!很高兴能提供帮助。
【解决方案2】:

获取第一个泛型参数的类型:

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

【讨论】:

  • 感谢@Yorye Nathan,您的回答对我帮助很大,非常接近我需要的,但我接受了安德鲁斯的回答,因为他提供了完整的上下文。
【解决方案3】:

如果我理解正确,你必须这样做:

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
  • 2018-05-15
  • 2011-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多