【问题标题】:Create an IEnumerable<Interface> from a bunch of ICollection<Implementation> 's in C#从 C# 中的一堆 ICollection<Implementation> 创建一个 IEnumerable<Interface>
【发布时间】:2015-11-25 16:08:15
【问题描述】:

我有一个由许多集合组成的类,如下所示:

public virtual ICollection<C> CStuff { get; set; }
public virtual ICollection<D> DStuff { get; set; }
public virtual ICollection<E> EStuff { get; set; }

每种类型都实现一个通用接口。

public class C : IStuff {}
public class D : IStuff {}
public class E : IStuff {}

我想创建一个包含我班级中所有 IStuff 的集合,如下所示:

IEnumerable<IEnumerable<IStuff>> AllStuffCollections 
{
    get { /* how??? */ }
}

public IEnumerable<IStuff> AllStuff 
{ 
   get 
   { 
       foreach (IEnumerable<IStuff> stuffCollection in AllStuffCollections) 
       {
           foreach (IStuff stuff in stuffCollection) 
           {
               yield return stuff;
           }
       }
   }
}

有什么方法可以在不显式添加每个集合的情况下完成此操作(反射可以)?如,我不想这样做:

IEnumerable<IEnumerable<IStuff>> AllStuffCollections 
{
    get 
    { 
        return new List<IEnumerable<IStuff>>() 
        { 
            CStuff.Cast<IStuff>, 
            DStuff.Cast<IStuff>,
            EStuff.Cast<IStuff>
        }
    }
}

随着时间的推移,这个类最终会添加更多IStuff 的集合,我担心当它发生变化时我会忘记将它们包含在AllStuffCollections 中。

此外,集合本身是惰性的(EF 填充),所以我不想做任何会迫使立即“查询所有事情”发生的事情。

【问题讨论】:

  • 您能否提供一个您想要的示例(即使它无效)。我不确定您是否更愿意使用显式添加集合的反射,或者您是否只想让程序知道您以某种方式拥有三个集合。
  • @Mephy 不显式添加每个集合!

标签: c# reflection collections interface casting


【解决方案1】:

如果反射没问题并且你不介意它的性能,你可以这样实现它:

public IEnumerable<IEnumerable<IStuff>> GetStuffCollections()
{
    var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var property in properties)
    {
        Type pt = property.PropertyType;
        if (pt.IsGenericType
            && pt.GetGenericTypeDefinition() == typeof(ICollection<>)
            && typeof(IStuff).IsAssignableFrom(pt.GetGenericArguments()[0]))
        {
            yield return (IEnumerable<IStuff>)property.GetValue(this);
        }
    }
}

【讨论】:

  • 太棒了,谢谢。这不仅解决了开箱即用的问题(我的测试仍然通过!),而且它给了我一个罗塞塔石碑,让我可以在未来使用反射和泛型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
相关资源
最近更新 更多