C# 如何将T类型的项目添加到列表<;T>;不知道T是什么?
我正在处理一个事件,该事件传递指向列表和T newitem的事件参数,我的工作是将newitem添加到列表中 如果不检查我知道T可能是的所有类型,我怎么能做到这一点 当前代码是以下几十行代码:C# 如何将T类型的项目添加到列表<;T>;不知道T是什么?,c#,wpf,generics,.net-4.0,C#,Wpf,Generics,.net 4.0,我正在处理一个事件,该事件传递指向列表和T newitem的事件参数,我的工作是将newitem添加到列表中 如果不检查我知道T可能是的所有类型,我怎么能做到这一点 当前代码是以下几十行代码: private void DataGridCollectionViewSource_CommittingNewItem(object sender, DataGridCommittingNewItemEventArgs e) { Type t = e.CollectionView.SourceColl
private void DataGridCollectionViewSource_CommittingNewItem(object sender, DataGridCommittingNewItemEventArgs e)
{
Type t = e.CollectionView.SourceCollection.GetType();
if (t == typeof(List<Person>))
{
List<Person> source = e.CollectionView.SourceCollection as List<Person>;
source.Add(e.Item as Person);
}
else if (t == typeof(List<Place>))
{
List<Place> source = e.CollectionView.SourceCollection as List<Place>;
source.Add(e.Item as Place);
}
...
private void DataGridCollectionViewSource\u CommittingNewItem(对象发送方,DataGridCommittingNewItemEventArgs e)
{
类型t=e.CollectionView.SourceCollection.GetType();
如果(t==类型(列表))
{
列表源=e.CollectionView.SourceCollection作为列表;
来源。添加(例如,项目作为个人);
}
else if(t==类型(列表))
{
列表源=e.CollectionView.SourceCollection作为列表;
来源。添加(例如,项目作为地点);
}
...
如果有可能,我更愿意这样做:
((List<T>) e.CollectionView.SourceCollection).Add((T)e.Item);
((列表)e.CollectionView.SourceCollection)。添加((T)e.Item);
有什么想法吗?这里不要使用泛型:
IList source = (IList)e.CollectionView.SourceCollection;
source.Add(e.Item);
您还可以使用
ICollection
代替IList
因为泛型集合实现了在系统中定义的基于对象的接口。集合
命名空间中,您可以执行以下操作:
((System.Collections.IList) e.CollectionView.SourceCollection).Add(e.Item);
当然,类型检查现在转移到运行时,因此您需要确保
e.Item
的类型正确,因为编译器无法在转换后检查它。您可以创建一个特定的类型化类吗
public class MyClass<ABC>
{
private void DataGridCollectionViewSource_CommittingNewItem(
object sender, DataGridCommittingNewItemEventArgs e)
{
Type t = e.CollectionView.SourceCollection.GetType();
if (t == typeof(List<ABC>))
{
List<ABC> source = e.CollectionView.SourceCollection as List<ABC>;
source.Add(e.Item as ABC);
}
}
}
公共类MyClass
{
私有无效DataGridCollectionViewSource\u提交新建项(
对象发送方,DataGridCommittingNewItemEventArgs(e)
{
类型t=e.CollectionView.SourceCollection.GetType();
如果(t==类型(列表))
{
列表源=e.CollectionView.SourceCollection作为列表;
来源。添加(例如,项目为ABC);
}
}
}
或者不取决于您尝试执行的操作的上下文……void AddItem(IEnumerable sourceCollection,对象项)
void AddItem<T>(IEnumerable sourceCollection, object item)
{
((List<T>)sourceCollectio).Add((T)item);
}
{
((列表)sourceCollectio)。添加((T)项);
}
然后
Type t=e.CollectionView.SourceCollection.GetType();
如果(t==typeof(List)){
AddItem(e.CollectionView.SourceCollection,e.Item);
}如果(t==typeof(List)){
AddItem(e.CollectionView.SourceCollection,e.Item);
}
“System.Collections.ICollection”不包含“Add”的定义,这就是我最初发布这篇文章的原因,但我没有尝试IList,这篇文章很有效。谢谢。@Alain啊,很公平-我不知道哪些方法在哪个接口中(iirc非泛型和泛型版本之间略有不同)作为一种健全性检查,是否有一种方法可以验证SourceCollection是否与e.Item属于同一类型?@Alain仅通过使用反射。但是,任何T等列表都会在错误时抛出异常,这很容易理解spot@Alain您可以测试源集合是否实现了通用的IList
,如果实现了,则获取键入参数,然后检查typeArg.IsAssignableFrom(e.Item.GetType())
。请注意,这是一种比检查类型相等性更好的方法,因为当然,e.Item
可能是一只羚羊
,而集合可能实现IList
。
Type t = e.CollectionView.SourceCollection.GetType();
if (t == typeof(List<Person>)) {
AddItem<Person>(e.CollectionView.SourceCollection, e.Item);
} else if (t == typeof(List<Place>)) {
AddItem<Place>(e.CollectionView.SourceCollection, e.Item);
}