从基类列表中查找字典匹配项

时间:2017-05-04 14:23:58

标签: c# list dictionary casting

我有一个很奇怪的问题。我正在开展一个大项目,我正在实现数百万行代码之后的核心功能。我不允许改变代码的某些部分,似乎我必须尝试这种方式。

我有两个班级AB。 A来自B。

public class B{}
public class A : B{}

我有SortedList<string, A>,我需要将SortedList投射到List<B>。在List<B>上操作,然后再将列表转换为SortedList

例如:

SortedList<string, B> items;
public List<A> GetItems()
{
   return items.Values.Cast<B>().ToList(); //Getting values works
}

public void SetItems(List<B> newItems)
{
    items = CastWithMagic(newItems); //How to make casting work?
}

A项目有两种可能的变化。

  • B(基类变量)的更改
  • 从列表中删除了项目。

我想将List<B>上的更改应用于SortedList<string, A>

2 个答案:

答案 0 :(得分:1)

  

A项目有两种可能的变化。

     
      
  • B(基类变量)的变化
  •   
  • 从列表中删除了项目。
  •   

对象的更改将反映在两个列表中,因为列表只包含引用到相同的对象。因此,您需要处理的是从List中删除的对象。我相信你必须遍历排序列表以查看是否已从列表中删除对象:

public void SetItems(List<B> newItems)
{
    foreach(string key in items.Keys)
    {
        if(!newItems.Contains(items[key] as B))
            items.Remove(key);
    }
}

请注意,这是低效率的,因为您在两个集合中循环,使其成为O(m*n) - 如果您的集合很小并且性能不是很关键那么您可能没问题,但从这开始并找到方法使它更有效(可能从源集合中删除而不是复制列表?)

答案 1 :(得分:1)

您可以使用Linq&#39; select&#39;这个功能。以此示例代码为例:

private void test()
{
    List<alphaClass> firstList = new List<alphaClass>();
    List<betaClass> secondList = firstList.Select(z => (betaClass)z).ToList();
}

public class alphaClass { }
public class betaClass : alphaClass { }

(这假设列表中的所有内容都可以转换为派生类。)

无论如何,linq的SELECT语句可用于将IEnumberable转换为不同的形式。在这种情况下,将它从一个类转换为另一个类。

编辑:哎呀 - 错过了排序列表部分。可以通过使用我为不同问题找到的扩展方法来处理这个问题:

public static class ExtensionMethod
{
    public static SortedList<TKey, TValue> ToSortedList<TSource, TKey, TValue>
(this IEnumerable<TSource> source,
 Func<TSource, TKey> keySelector,
 Func<TSource, TValue> valueSelector)
    {
        var ret = new SortedList<TKey, TValue>();
        foreach (var element in source)
        {
            ret.Add(keySelector(element), valueSelector(element));
        }
        return ret;
    }

}

...然后,从这里开始,您可以像这样使用该扩展名:

SortedList<string, betaClass> myList = new SortedList<string, betaClass>();
SortedList<string, alphaClass> secondList;
secondList = myList.ToSortedList(kvp => kvp.Key, kvp => (alphaClass) kvp.Value);