无法将Systems.Collections.GenericList <t>转换为T.

时间:2018-01-06 20:34:50

标签: c# .net

我的字典值是一个列表。我需要阅读每个列表以提取字段。但是在foreach循环中得到以下错误

  

无法转换类型   System.Collections.Generic.List<UserQuery.Employee>来   UserQuery.Employee

如果我在var iValue的注释行中使用firstorDefault,它会起作用。但是我会在我正在阅读的字典中检查多条记录(尽管在这个例子中,我硬编码为1,以测试我的代码)。

void Main()
{
    var svalue =1;
    List<Employee> emplist = new List<Employee>()
    {
         new Employee{ EID=10, Ename="John"},
         new Employee{ EID=11, Ename="Adam"},
         new Employee{ EID=12, Ename="Ram"}
    };
    List<Employee> emplist1 = new List<Employee>()
    {
         new Employee{ EID=1, Ename="Jo"},
         new Employee{ EID=1, Ename="Ad"},
         new Employee{ EID=1, Ename="Ra"}
    };

    var dict1 = new Dictionary<int, List<Employee>>();
    dict1.Add(1, emplist);
    dict1.Add(2, emplist1);

    //var ivalue = dict1.FirstOrDefault(x => x.Key == svalue).Value.ToList();
    var ivalue = dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value);

    Console.WriteLine(ivalue);
    foreach (Employee emp in ivalue)
    {
        Console.WriteLine(emp.EID);
    }
}

class Employee
{
    public int EID { get; set;}
    public string Ename {get; set;}
}

6 个答案:

答案 0 :(得分:2)

您当前的代码

 var ivalue = dict1
   .Where(kvp => dict1.ContainsKey(1)) //TODO: Very strange condition: check it
   .Select(x => x.Value);

返回IEnumerable<List<Employee>>作为结果(ivalue)。由于您只需要IEnumerable<Employee>,因此您必须展平结果:

 var ivalue = dict1
   .Where(kvp => dict1.ContainsKey(1))
   .SelectMany(kvp => kvp.Value); // kvp: we still have key-value pair

然而,这不是我们处理字典的方式;你可能正在寻找这样的东西(让我们保留一些Linq: - .Select(emp => emp.EID)):

 if (dict1.TryGetValue(1, out var ivalue)) // do we have corresponding value?
   Console.WriteLine(String.Join(Environment.NewLine, ivalue // if yes, print them out
     .Select(emp => emp.EID)));

答案 1 :(得分:1)

这不是你通常使用词典的方式。你想做的是这样的:

if (dict1.ContainsKey(1)) // if the dictionary contains the key
{
    var ivalue = dict1[1]; // get the value of that key
}

有了这个,您正在使用最有效的方式来搜索字典。所以你应该这样做:

var dict1 = new Dictionary<int, List<Employee>>();
dict1.Add(1, emplist);
dict1.Add(2, emplist1);

if (dict1.ContainsKey(1))
{
    var ivalue = dict1[1];

    Console.WriteLine(ivalue); // this will print System.Collections.Generic.List<Employee>
    foreach (Employee emp in ivalue)
    {
        Console.WriteLine(emp.EID);
    }
}

另一种选择是使用TryGetValue

var dict1 = new Dictionary<int, List<Employee>>();
dict1.Add(1, emplist);
dict1.Add(2, emplist1);
List<Employee> ivalue = null;
if (dict1.TryGetValue(1, out ivalue))
{
    Console.WriteLine(ivalue); // this will print System.Collections.Generic.List<Employee>
    foreach (Employee emp in ivalue)
    {
        Console.WriteLine(emp.EID);
    }
}

答案 2 :(得分:0)

Where收到两次KeyValuePair,当然对KeyValuePair都返回true,因为你总是问同样的问题。字典是否包含密钥== 1?是。因此,Where的返回是两个List<Employee>元素的可枚举,无法转换为单个通用列表。

var ivalue = dict1.FirstOrDefault(kvp => dict1.ContainsKey(1));
if(ivalue.Value != null)
    foreach (Employee emp in ivalue.Value)
       Console.WriteLine(emp.EID);

当然,正如评论中所指出的,Linq的这种使用是没有根据的,因为你的代码可以简化为

List<Employee> empList;
// Try directly to get the List<Employee> that match the Key
// if found you have the empList initialized with the matching list
// otherwise TryGetValue returns false.
if(dict.TryGetValue(1, out empList))
    foreach (Employee emp in empList)
       Console.WriteLine(emp.EID);

答案 3 :(得分:0)

执行var ivalue = dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value);时,您使用Where方法过滤列表,然后使用Select选择所有值。

您获得该异常是正常的,因为Select会为您提供一个列表,而不是一个条目。您应该foreach列出该列表,或使用FirstOrDefault并获得1个单值。

foreach (var value in dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value))
{
    // ...
}

或者

var ivalue = dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value).FirstOrDefault();

答案 4 :(得分:0)

var ivalue = dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value);

将返回带有List类型元素的'IEnumerable'。 所以你需要两个嵌套的foreach循环:

'outer'用于遍历从Dictionary中检索到的所有列表,'inner'用于迭代当前List中的所有员工。

答案 5 :(得分:0)

我不认为你的意思是:dict1.ContainsKey(1))

我想你是在这之后:

var ivalue = dict1.FirstOrDefault(d =>d.Key==1 ).Value ;


if (ivalue!=null)
foreach (Employee emp in ivalue)
{
    Console.WriteLine(emp.EID);
}

请注意:

var ivalue = dict1.Where(kvp => dict1.ContainsKey(1)).Select(x => x.Value);

检查字典是否为1作为键,但不会在结果中考虑该键。

相关问题