我有各种项目类型的集合列表。
该列表的类型为List<IEnumerable>
;因为IEnumerable
是ICollection<T>
中唯一的非通用接口,我需要添加例如此列表中包含ICollection<Contact>
和ICollection<Partnership>
个集合。
稍后,在实体实用程序代码中,我需要清除集合。到目前为止我找到的唯一解决方案是:
collection.GetType().GetInterface("ICollection`1").InvokeMember("Clear",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
null,
collection,
new object[0]);
我可以使用更优雅的东西吗?
答案 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();
会做