我有一个很奇怪的问题。我正在开展一个大项目,我正在实现数百万行代码之后的核心功能。我不允许改变代码的某些部分,似乎我必须尝试这种方式。
我有两个班级A
和B
。 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>
答案 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);