Cannot implicitly convert type void to List

I have below class structure:

class Child
{
    public List<ParentData> ParentData { get; set; }
}

class ParentData
{
    public string FatherName {get;set;}
    public string MotherName {get;set;}
    public List<GrandParentData> GrandParentData{ get; set; }
}

class GrandParentData
{
    public string GrandFatherName {get;set;}
    public string GrandMotherName {get;set;}
}

When I am trying to fill this:

foreach (var item in res)
{
    obj.StoryData.Add(
        new StoryData
        {
            FatherName = item.FatherName,
            MotherName = item.Description,                                                                        
            GrandParentData = new List<GrandParentData().Add(
                new GrandParentData 
                { 
                    GrandFatherName = "",
                    GrandMotherName = ""
                }
            );
        }                            
    );
}

This is giving me error when I am trying to add data to GrandParentList List:

Cannot implicitly convert type void to List

Do I need to change my class structure? What edits should I make to my code?

Jon Skeet
people
quotationmark

So this part is the problem:

GrandParentData=new List<GrandParentData().Add(
    new GrandParentData { GrandFatherName = "",GrandMotherName =""});

There are three problems here:

  • You're not closing the type argument
  • You've got a semi-colon at the end, despite this being part of an object initializer
  • You're calling the Add method, which returns void - hence the compile-time error

As further explanation for the last part, ignoring the fact that you're in an object initializer, your code is equivalent to trying to write something like:

List<int> list = new List<int>().Add(1);

That's invalid because new List<int>().Add(1) doesn't return anything. To use Add like that explicitly, you'd need to declare the variable separately:

List<int> list = new List<int>();
list.Add(1);

That doesn't work within an object initializer of course, as you need to provide a single expression to set the property.

The solution is to use a collection initializer instead. In our simple case that would be:

List<int> list = new List<int> { 1 };

In your more complex case, you'd do this:

GrandParentData = new List<GrandParentData>
{ 
    new GrandParentData { GrandFatherName = "", GrandMotherName = "" }
}

Alternatively, you could change GrandParentData to be a read-only property, but have it already initialized, like this:

public List<GrandParentData> GrandParentData { get; } =
    new  List<GrandParentData>();

Then you could just write:

GrandParentData =
{ 
    new GrandParentData { GrandFatherName = "", GrandMotherName = "" }
}

... and the new GrandParentData would be added to the existing collection.

people

See more on this question at Stackoverflow