C# 如何将T类型的项目添加到列表<;T>;不知道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

我正在处理一个事件,该事件传递指向列表和T newitem的事件参数,我的工作是将newitem添加到列表中

如果不检查我知道T可能是的所有类型,我怎么能做到这一点

当前代码是以下几十行代码:

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