如果我将LINQ ./byfn.sh up -o kafka
扩展方法应用于Take
,如何将结果转换为新的SortedList<int, int>
?
从我得到的运行时错误中,Take方法的结果是一个SortedList<int, int>
,无法转换为EnumerablePartition
控制台应用程序中的Main方法编译正常,但是在将list.Take(2)转换为SortedList时在运行时抛出错误
SortedList<int, int>
我希望 static void Main(string[] args)
{
Console.WriteLine("List");
var list = new SortedList<int, int>();
list.Add(2, 10);
list.Add(8, 9);
list.Add(3, 15);
foreach (KeyValuePair<int, int> item in list){
Console.WriteLine(item.Value);
};
Console.WriteLine("Short List");
var shortlist = (SortedList<int, int>)list.Take(2);
foreach (KeyValuePair<int, int> item in shortlist)
{
Console.WriteLine(item.Value);
};
Console.Read();
}
方法的结果是一个新的Take
,或者至少可以转换为SortedList<int, int>
,因为这是原始类型
这是我遇到的运行时错误:
SortedList<int, int>
编辑:
我对LINQ和Generics比较陌生,但是由于提供了出色的答案,我为可读性创建了新的扩展方法:
Unable to cast object of type 'EnumerablePartition`1[System.Collections.Generic.KeyValuePair`2[System.Int32,System.Int32]]' to type 'System.Collections.Generic.SortedList`2[System.Int32,System.Int32]'
现在,创建我的候选清单:
static class Extensions {
public static SortedList<TKey, TValue> ToSortedList<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> collection)
{
var dictionary = collection.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
return new SortedList<TKey, TValue>(dictionary);
}
}
我当时想像上面的东西可能已经可用!
答案 0 :(得分:8)
我希望Take方法的结果是一个新的SortedList,或者至少可以转换为SortedList,因为这是原始类型。
嗯,这种方式不太有效。如果您从一袋糖果中Take(2)
,则有两种糖果。您不会因为一个原始的糖果装在袋子里而神奇地带了两个糖果在新袋子里。
从技术上讲,Take
方法采用任何类型的IEnumerable<>
并返回相同类型的IEnumerable<>
。该过程中会丢失原始容器类型的信息。
现在很明显,就像在我们的糖果示例中一样,如果您想要从大袋子中拿出每个都有两个小糖果的小袋子,那么没有人会阻止您重新包装它们。同样在这里。如果需要排序列表,请从结果中创建一个新的排序列表。但这是手动的。
答案 1 :(得分:2)
您可以使用SortedList
constructor
var sortedList = new SortedList<int, int>(list.Take(2).ToDictionary(x => x.Key, x => x.Value));
答案 2 :(得分:1)
Take
不返回SortedList
,因此您需要以一种或另一种方式创建新的东西:
var shortList = new SortedList<int, int>();
foreach (var x in list.Take(2))
shortList.Add(x.Key, x.Value);
答案 3 :(得分:1)
鉴于这是原始类型
是的,但是Take()
是IEnumerable<T>
的扩展方法,并且SortedList<TKey, TValue>
实现了IEnumerable<KeyValuePair<TKey, TValue>>
。
因此,您从Take()
返回的类型与您调用它的源没有任何关系-它仅返回IEnumerable<T>
的实现,其中T
是与您调用的T
的{{1}}类型相同。
相反,使用分区及其appropriate constructor实例化一个新列表:
IEnumerable<T>