有没有一种很好的方法来清除ICollection <t>而不知道T?</t>

时间:2013-07-03 14:21:20

标签: c# .net generics

我有各种项目类型的集合列表。 该列表的类型为List<IEnumerable>;因为IEnumerableICollection<T>中唯一的非通用接口,我需要添加例如此列表中包含ICollection<Contact>ICollection<Partnership>个集合。

稍后,在实体实用程序代码中,我需要清除集合。到目前为止我找到的唯一解决方案是:

collection.GetType().GetInterface("ICollection`1").InvokeMember("Clear",
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
        null,
        collection,
        new object[0]);

我可以使用更优雅的东西吗?

3 个答案:

答案 0 :(得分:9)

如果您被ICollection<T>限制为最低类型,则选项不多。涉及DLR的一个不太常见的实现是使用dynamic并对其进行鸭式输入:

    static void Main(string[] args)
    {
        var listOfLists = new List<IEnumerable>();

        var names = new List<string>();
        var ages = new List<int>();

        listOfLists.Add(names);
        listOfLists.Add(ages);

        foreach (dynamic list in listOfLists)
        {
            list.Clear();
        }
    }

或者您可以对可能实现的接口进行假设,并对定义了Clear的接口进行测试:

        foreach (var list in listOfLists)
        {
            if (list is IList)
            {
                (list as IList).Clear();
            }
        }

如果您可以进入类型层次结构,请创建您的馆藏使用的自己的界面,并定义您自己的Clear

这主要是一个问题,因为pre -.NET 2.0集合和接口与.NET 2.0集合和接口不能很好地融合。

答案 1 :(得分:0)

您可以为业务类使用通用接口,例如IObject(或者甚至是object类)。试试这个:

class Program
{
    static void Main(string[] args)
    {
        var list = new MyList();

        var contacts = new ContactCollection();
        var partnerships = new PartnershipCollection();

        contacts.Add(new Contact());
        partnerships.Add(new Partnership());

        list.Add(contacts);
        list.Add(partnerships);

        list.ClearCollections();
    }

    class MyList : List<ICollection<IObject>>
    {
        public void ClearCollections()
        {
            this.ForEach((a) => a.Clear());
        }
    }

    interface IObject { }
    class Contact : IObject { }
    class Partnership : IObject { }
    class ContactCollection : ICollection<IObject> { }
    class PartnershipCollection : ICollection<IObject> { }
}

答案 2 :(得分:-2)

为什么需要使用Reflection?因为ICollection接口包含Clear方法,所以实现它的任何具体类型都将覆盖它。

如此简单

ICollection collection = new List<Something>();
collection.Clear();

会做