1

is it possible to store nested structs or classes in lists using c#?

looking at the following code segments.

Nested Scruct:

struct structBooks
{
    public string strBookName;
    public string strAuthor;
    public structPubished publishedDate;
}

struct structPubished
{
    public int intDayOfMonth;
    public int intMonthOfYear;
    public int intYear;
}

saving as a list:

  static void AddBookToList()
    {
        structBooks testStruct = new structBooks();
        testStruct.strBookName = newBookName;
        testStruct.strAuthor = newAuther;
        testStruct.publishedDate.intYear = intNewYear;
        testStruct.publishedDate.intMonthOfYear = intNewMonthOfYear;
        testStruct.publishedDate.intDayOfMonth = intNewDayOfMonth;

        static List<structBooks> listBooks = new List<structBooks>();
        listBooks.Add(new structBooks()
        {
            strBookName = newBookName,
            strAuthor = newAuther,
            publishedDate.intYear = intNewYear,
            publishedDate.intMonthOfYear = intNewMonthOfYear,
            publishedDate.intDayOfMonth = intNewDayOfMonth
        });
    }

creating all the testStruct's works as expected.

When it comes to storing the struct as a list strBookName and strAuthor both work. However, when it comes to the nested publishedDate Visual Studio tells me "invalid initialiser member declarator".

the list its self is defined in the Main method, I just added it so you can see how it's defined.

what am i missing?

Fildor
  • 14,510
  • 4
  • 35
  • 67
Sara Payne
  • 75
  • 8
  • 7
    Have you considered using DateTime? – Chris Nevill Jan 21 '19 at 09:03
  • Can you try using `{}` to create and initialize the `publishedDate` – bit Jan 21 '19 at 09:03
  • 1
    You can't use dot syntax in initialisers, you can only use `new`. So you have to say `publishedDate = new structPubished { intYear = ..., intMonthOfYear = ..., intDayOfMonth = ... }` – Ian Kemp Jan 21 '19 at 09:04
  • See [Object Initializer](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers) for detailed information. – AlexWei Jan 21 '19 at 09:10

5 Answers5

3

Use new to initialize your publishedDate struct, just as you do with structBooks.

  List<structBooks> listBooks = new List<structBooks>();
  listBooks.Add(new structBooks()
  {
    strBookName = "bookName",
    strAuthor = "author",
    publishedDate = new structPubished
      {
        intDayOfMonth = 1,
        intMonthOfYear = 1,
        intYear = 1000
      }
  });
Mikołaj Mularczyk
  • 959
  • 12
  • 20
1

You need to initialize your struct using the new keyword

List<structBooks> listBooks = new List<structBooks>();
listBooks.Add(new structBooks()
{
    strBookName = "bookName",
    strAuthor = "author",
    publishedDate = new structPubished
      {
        intDayOfMonth = intNewDayOfMonth,
        intMonthOfYear = intNewMonthOfYear,
        intYear = intNewYear
      }
});

Hope you also realize that you don't actually need to create the structPublished in the first place and could use in-build DateTime.

This would change your structBooks as

struct structBooks
{
    public string strBookName;
    public string strAuthor;
    public DateTime publishedDate;
}

and you can add as

List<structBooks> listBooks = new List<structBooks>();
  listBooks.Add(new structBooks()
  {
    strBookName = "bookName",
    strAuthor = "author",
    publishedDate = new DateTime(intNewYear,intNewMonthOfYear,intNewDayOfMonth)
  });

The inbuild DateTime struct provides a lot of other functionalities which can be useful for your application.

Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • ty for that, it is a better way in this instance, it was the process I wanted to understand. The answer is still good though :) – Sara Payne Jan 21 '19 at 09:29
0

Change this:

testStruct.publishedDate.intYear = intNewYear;
testStruct.publishedDate.intMonthOfYear = intNewMonthOfYear;
testStruct.publishedDate.intDayOfMonth = intNewDayOfMonth;

to this:

testStruct.publishedDate = new structPublished {
  intYear = intNewYear,
  intMonthOfYear = inNewMonthOfYear,
  intDayOfMonth = intNewDayOfMonth
};

You can't initialise something by setting its fields or properties - C# still doesn't know the type of the thing you're trying to initialise. Instead, you need to use the new keyword which is designed for initialising objects.

8ytan
  • 300
  • 1
  • 7
  • See [Object Initializer](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers) for detailed information. – AlexWei Jan 21 '19 at 09:12
0

This is the correct implementation:

    static void AddBookToList()
    {
        structBooks testStruct = new structBooks();
        testStruct.strBookName = newBookName;
        testStruct.strAuthor = newAuther;
        testStruct.publishedDate.intYear = intNewYear;
        testStruct.publishedDate.intMonthOfYear = intNewMonthOfYear;
        testStruct.publishedDate.intDayOfMonth = intNewDayOfMonth;

        List<structBooks> listBooks = new List<structBooks>();
        listBooks.Add(new structBooks()
        {
            strBookName = newBookName,
            strAuthor = newAuther,
            publishedDate = new structPubished()
            {
                intYear = intNewYear,
                intMonthOfYear = intNewMonthOfYear,
                intDayOfMonth = intNewDayOfMonth
            }
        });
    }

The difference between the creation of testStruct and the one inserted to the list, is the way you initialize.

When you do

structBooks testStruct = new structBooks();

it initialize every object inside by using the default constructor, that's why you don't have to type

testStruct.publishedDate = new structPubished();

differently, when you declare the initialization by providing values of the Object, you must specify everything.

Marco Salerno
  • 5,131
  • 2
  • 12
  • 32
0

You need to use nested object initializer syntax. Notice there is no new keyword required to create the nested struct.

listBooks.Add
(
    new structBooks
    {
        strBookName = newBookName,
        strAuthor = newAuther,
        publishedDate = 
        {
            intYear = 2018, 
            intMonthOfYear = 1, 
            intDayOfMonth = 2 
        }
    }
);
John Wu
  • 50,556
  • 8
  • 44
  • 80