HXD
HXD

Reputation: 506

Cannot convert from 'System.Collections.Generic.IEnumerable to System.Collections.Generic.IEnumerable<string>

I have a spec flow test with the following test data

    | Field   | Value  |
    | Message | test   |
    | Message2| test2  |

I have a class that gets data from spec flow table

  public List<String> GetInputMessage(Table table)
    {
        var elements = new List<string>();
        var data = table.CreateSet<SpecFlowData>().ToList();
        elements.AddRange(from item in data
                          let field = item.Field
                          let value = item.Value
                          select new List<string>(new string[] { field ,value}));
        return elements;
    }

but I am getting error:

cannot convert from 'System.Collections.Generic.IEnumerable <System.Collections.Generic.List<string>>' to System.Collections.Generic.IEnumerable<string>

What is the other way of getting the field and value from the table? thank you

Upvotes: 0

Views: 2687

Answers (4)

Scott Chamberlain
Scott Chamberlain

Reputation: 127563

While the accepted answer shows how to do it with a dictionary, if you have multiple of the same Field you won't be able to use it. In this situation I would just make a class representing each row, it is not much code and very similar to your original answer (I also cleaned it up some removing some of the extra bits you did not need to have).

//Add this somewhere in your project.
class MyDataRow
{
    public string Field {get; set;}
    public string Value {get; set;}
}

//back to your orginal function.
public List<MyDataRow> GetInputMessage(Table table)
{

    var data = table.CreateSet<SpecFlowData>(); //the ToList() that was here is not needed, just use the IEnumerable<SpecFlowData> or IQueryable<SpecFlowData> that CreateSet<SpecFlowData>() returns.
    var elements = (from item in data
                    //The two let clauses that where here are unessesary too.
                    select new MyDataRow {Field = item.Field, Value = item.Value}
                   ).ToList();
    return elements;
}

Upvotes: 1

J. Lennon
J. Lennon

Reputation: 3361

Check the declare types and the result after the linq code..

To solve you can do this:

public List<String> GetInputMessage(Table table)
{
    var elements = new List<List<string>>();
    var data = table.CreateSet<SpecFlowData>().ToList();
    elements.AddRange(from item in data
                      let field = item.Field
                      let value = item.Value
                      select new List<string>(new string[] { field ,value}));
    return elements.SelectMany(a => a).ToList();
}

But there are other ways to solve your problem...

Upvotes: 0

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

AddRange method expecting an IEnumerable<string> but you are trying to pass it IEnumerable<List<string>>. Try this:

elements.AddRange(data.SelectMany(x => new [] { x.Field, x.Value}));

Or if you want to concatenate the Field and Value into single row:

elements.AddRange(data.Select(x => string.Join(",", x.Field,x.Value));

Upvotes: 1

Brian R. Mullin
Brian R. Mullin

Reputation: 423

Your field name and value pairs appear to be a good match for a dictionary collection instead of list collection.

public Dictionary<string, string> GetInputMessage(Table table)
{
    var elements = new Dictionary<string, string>();
    foreach(var item in table.CreateSet<SpecFlowData>())
    {
       elements.Add(item.Field, item.Value);
    }
    return elements;
}

Upvotes: 2

Related Questions