从 C# 中的一堆 ICollection<Implementation> 创建一个 IEnumerable<Interface>

Create an IEnumerable<Interface> from a bunch of ICollection<Implementation> 's in C#

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

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

我想在我的 class 中创建一个包含所有 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>
        }
    }
}

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

此外,集合本身是惰性的(填充了 EF),所以我不想做任何会迫使立即 "query all the things" 发生的事情。

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

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