代码之家  ›  专栏  ›  技术社区  ›  ChrisBD

在字典中选择并删除特定对象类型的最有效方法

  •  2
  • ChrisBD  · 技术社区  · 16 年前

    好的,我有一系列基于基类的对象,它们随机存储在Dictionary对象中。例如

    class TypeA
    {
       public int SomeNumber {get; set;}
       public void SomeFunction()
    }
    
    class TypeB : TypeA
    {
       public string SomeString {get; set;}
    }
    
    class TypeC : TypeA
    {
       public bool StuffReady()
    }
    
    
    Dictionary listOfClasses <long, TypeA>;
    

    这样做的最佳方式是什么?

    4 回复  |  直到 16 年前
        1
  •  5
  •   LukeH    16 年前

    如果您确定只有一个匹配对象(或者如果您只想删除第一个匹配对象):

    var found = listOfClasses.FirstOrDefault
        (
            x => (x.Value is TypeB) && (((TypeB)x.Value).SomeString == "123")
        );
    
    if (found.Value != null)
    {
        listOfClasses.Remove(found.Key);
    }
    

    如果可能存在多个匹配对象,并且您希望将其全部删除:

    var query = listOfClasses.Where
        (
            x => (x.Value is TypeB) && (((TypeB)x.Value).SomeString == "123")
        );
    
    // the ToArray() call is required to force eager evaluation of the query
    // otherwise the runtime will throw an InvalidOperationException and
    // complain that we're trying to modify the collection in mid-enumeration
    foreach (var found in query.ToArray())
    {
        listOfClasses.Remove(found.Key);
    }
    
        2
  •  3
  •   JaredPar    16 年前

    TypeA类和字典键之间似乎没有映射。键的类型为long,并且该类上没有该类型的属性。因此,您必须搜索KeyValuePair实例的集合,这将使您能够直接访问密钥。

    试试下面的方法

    var found = listOfClasses
      .Where(p => p.Value.SomeString == "123").
      .Where(p => p.Value.GetType() == typeof(TypeB))
      .Single();
    listOfClasses.Remove(found.Key);
    
        3
  •  0
  •   Harishbb    16 年前

    如果您是从性能的角度来看,那么for循环是更好的方法,但如果您是从代码的紧凑性或代码管理的角度来看,那么LINQ就是最好的方法。

        4
  •  0
  •   Vivek    16 年前

    您需要在每个对象中存储运行长度。添加一个属性,例如 RunningLength 在里面 TypeA A型 对象和其他 TypeB

    无论何时创建对象(从 A型 B型 将其添加到第二个字典:

    Dictionary listOfClasses <long, TypeA>;
    Dictionary listOfTypeBClasses <string, TypeB>;
    
    TypeA newOject = TypeAFactory.Create();
    
    if(newObject is TypeB)
    {
      TypeB objB = newObj as TypeB;
      listOfTypeBClasses[objB.SomeString] = objB;
    }
    

    使用SomeString=“123”删除类型为B的对象

    if(listOfTypeBClasses.ContainsKey("123"))
    {
      long keyA = listOfTypeBClasses["123"].RunningLength;
      listOfClasses.Remove(keyA);
      // if required remove the item from listOfTypeBClasses as well
      listOfTypeBClasses.Remove("123");
    }