我有一个返回列表的List<KeyValuePair<int,string>>
方法;但是,我收到了一个错误:
无法将源类型
System.Collections.Generic.List<{Key:int, Value:string}>
转换为目标类型System.Collections.Generic.KeyValuePair<'int,string'>>
。
我正在尝试将Linq select语句转换为新列表,但我不明白初始化列表是否存在问题,或者我是如何获取Linq语句中的值的。
以下是方法:
public static List<KeyValuePair<int,string>> GetStatus(int status)
{
List<KeyValuePair<int,string>> st = SelectList.GetStatuses();
List<KeyValuePair<int,string>> tp;
switch(status)
{
case (int)Status.Completed:
tp = st.Where(s => s.Key == (int)Status.Completed ||
s.Key == (int)Status.NotValid)
.Select(s => new { s.Key, s.Value }).ToList();
case (int)Status.Open:
tp = st.Where(s => s.Key == (int)Status.Open ||
s.Key == (int)Status.Reviewed)
.Select(s => new { s.Key, s.Value }).ToList();
default:
break;
}
return tp;
}
这是填充列表的方法:
public static List<KeyValuePair<int, string>> GetStatuses()
{
using (var con = new SqlConnection())
{
var sql = @"SELECT ID [Key], Text [Value] from Statuses";
return (con.Query<KeyValuePair<int, string>>(sql.ToString(), commandType: commandType:Text) ?? Enumerable.Empty<KeyValuePair<int, string>>()).ToList();
}
}
答案 0 :(得分:5)
当您编写new { s.Key, s.Value }
时,您正在实例化一个包含属性Key
和Value
的新匿名类型。相反,您可能希望通过编写KeyValuePair
来使用new KeyValuePair(s.Key, s.Value)
的构造函数。
另请注意,您的Where
子句已经过滤了KeyValuePairs
的列表,因此甚至不需要投影。换句话说,在这种情况下,您可以删除整个Select
语句。
因此,您可以使用KeyValuePair
构造函数并编写:
tp = st.Where(s => s.Key == (int)Status.Open || s.Key == (int)Status.Reviewed)
.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value)).ToList();
或者,更好的是,只需删除Select
语句:
tp = st.Where(s => s.Key == (int)Status.Open || s.Key == (int)Status.Reviewed).ToList();
关于匿名类型的更多信息:匿名类型是一种C#功能,允许您使用自定义属性制作快速的临时类。它们对Linq
个查询特别有用。当您的程序编译时,会发出一个新的匿名类型,其中包含2个名为Key
和Value
的属性。你可以在没有名字的情况下创建一个具有2个属性的新类(完全成熟的类和匿名类之间存在一些其他差异,但这是一种考虑它的便捷方式)。您的方法应返回KeyValuePairs
列表,但您已提供此新类型的对象列表。详细了解他们here。
作为一般性小调,您根本不需要声明tp
变量。相反,您可以在return
声明中switch
:
答案 1 :(得分:4)
正如其他人已经指出的那样,您在Select
创建了一个新的匿名类型,而不是KeyValuePair
。但是,您已经在使用KeyValuePair
,因此您甚至不需要Select
tp = st.Where(...where...).ToList();
实际上没有必要重新实例化Select
中的对象(除非你想要一个新的引用......但在这种情况下KVP是不可变的)。 Where.ToList
更具表现力,仅仅是因为它不那么容易,至少恕我直言
答案 2 :(得分:2)
您无法将匿名对象{ Key, Value }
列表分配给类型为KeyValuePair<int,string>
的变量。如果您要重复使用KeyValuePair
调用返回的相同GetStatuses()
实例,则只需删除Select
投影即可。否则,将每个键值对投影到KeyValuePair<int,string>
类型的新实例(下面的取消注释行):
switch(status)
{
case (int)Status.Completed:
tp = st.Where(s => s.Key == (int)Status.Completed || s.Key == (int)Status.NotValid)
//.Select(s => new KeyValuePair<int, string>(s.Key, s.Value))
.ToList();
break; // also make sure you have break here
case (int)Status.Open:
tp = st.Where(s => s.Key == (int)Status.Open || s.Key == (int)Status.Reviewed)
//.Select(s => new KeyValuePair<int, string>(s.Key, s.Value))
.ToList();
break;
}