0

I create a struct, let's call it Example.

Here it is :

[System.Serializable]
public struct Example 
{
    public enum Categories {example, test}
    [SerializeField] private Categories lineCategory ; 
    public Categories _lineCategory { get {return lineCategory;} }

    [SerializeField] private Translation[] translations; 
    public Translation[] _translations { get {return translations;}}
}

And here is the class Translation :

[System.Serializable]
public struct Translation
{
    public enum Languages {fr, en}
    [SerializeField] private Languages language ; 
    public Languages _language { get {return language;}}

    [TextArea] [SerializeField] private string line ; 
    public string _line { get {return line;}}
}

When I'm using it with unity, there are 0 problems, the System.Serializable make it easy to use.

But, for practical reason, I want to create one with code.

Here is an idea of what I want to create :

 private Example test = new Example {
        lineCategory = Example.Categories.test, 
        lines = new Translation {
            {language = Languages.fr,
            line = "test ligne"},
            {language = Languages.en,
            line = "test line"},
        }
    }

Obviously it doesn't work, first because of private / public but, there are more problems and I really can't figure them.

I'm showing here only a small part of my problem, because I would like to create a really big struct for all the translations in my game so there will be more than just one lines but this way you'll understand the problem I think.

Does someone know how to create a new Example() in a good way ?

Pierre Marsaa
  • 346
  • 2
  • 10
  • `lines = new[] { new Translation {language = Languages.fr, line = "test ligne"}, new Translation {language = Languages.en, line = "test line"}, .... },` – Charlieface Jul 21 '22 at 10:00
  • Does this answer your question? [All possible array initialization syntaxes](https://stackoverflow.com/questions/5678216/all-possible-array-initialization-syntaxes) also https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers – Charlieface Jul 21 '22 at 10:01
  • 1
    Is there a reason you're using the opposite naming convention for public/private members to the norm? (Normally, the public name is "normal" and the private one is augmented by e.g. a leading underscore) – Damien_The_Unbeliever Jul 21 '22 at 10:15
  • @Charlieface your first answer was the one I was looking for ! Do you want to write it in the answer so I can check it ? – Pierre Marsaa Jul 21 '22 at 13:21

1 Answers1

1

You could declare your properties as init only.

public string Translation[] { get => _translations ; init => _translations = value;}

You would also need to use correct types, i.e. assign an actual array: lines = new[]{ new Translation{...}}

Another option would be to provide constructors that take the parameters you need. This is in my opinion better since it forces the creator of the object to populate all required fields.

public struct Example 
{
...
public Example(Categories lineCategory, Translation[] translations){
    _lineCategory = lineCategory;
    _translations = translations;
}

You might also consider using dedicated "DTO" types. I.e. one TranslationDTO type only used for serialization, and Translation type used in all other code. This pattern can help separate any logic in your types from things needed for serialization, and example would be that many serialization libraries require public setters. But this is less of a concern if you have little to no logic in your types.

JonasH
  • 28,608
  • 2
  • 10
  • 23