从C#中的一堆ICollection <implementation>中创建一个IEnumerable <interface>

时间:2015-08-31 15:06:48

标签: c# reflection collections interface casting

我有一个由许多集合组成的类:

<script src="app/app.module.js"></script>
    <script src="app/app.config.js"></script>
    <script src="app/controllers/services/Cart.resource.js"></script>
    <script src="app/controllers/loginController.js"></script> 

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

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

我想在我的班级中创建所有IStuff的集合,如下所示:

public class C : IStuff {}
public class D : IStuff {}
public class E : 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中。

此外,收藏品本身是懒惰的(EF填充),所以我不想做任何会迫使立即查询所有事情的事情。发生。

1 个答案:

答案 0 :(得分:4)

如果反思没问题且你不介意其表现,你可以这样实现:

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