1

Using Visual Studios 2010 C#

so i am making a struct of data for a c# project, that will among it's members include an array of type another struct. So for example here is a stripped down idea of my code:

    private struct scores
    {

        public double finalScore;


    };

    private struct information
    {
        public string name;
        public scores[] scoreList;

    };

I am getting the following warning when I write this:

Error 1 'WindowsFormsApplication1.main.information.scoreList': cannot have instance field initializers in structs

I am wondering what is the correct way to declare the scores[] scoreList aspect of the struct information, so I can have the array size set to 10?

Things I have tried:

  • If I try

    public scores[] scoreList = new scores[10]

I get the following error

Error 1 'WindowsFormsApplication1.main.information.scoreList': cannot have instance field initializers in structs

2
  • 5
    I suggest using a class instead of a struct. Commented Jun 25, 2013 at 4:47
  • 1
    From Choosing Between Class and Struct (MSDN): structs are meant to "logically represent a single value, similar to primitive types" and have an "instance size under 16 bytes". As @Richard said, consider using a class instead of a struct for information. You should almost certainly not be using a struct with an array. Commented Jun 25, 2013 at 5:02

4 Answers 4

4

In structs you can do initialization within constructors only:

  struct information {
    public string name;
    public scores[] scoreList;

    // Constructor
    public information(String nameValue) {
      name = nameValue;
      scoreList = new scores[10]; // <- It's possible here
    }
  };
Sign up to request clarification or add additional context in comments.

Comments

4

The problem here is that you're making the structs private, which means you can't make instances of them. Make them public. And also get rid of the ; at the end

public struct scores
{

    public double finalScore;


}

public struct information
{
    public string name;
    public scores[] scoreList;

}

I typically don't use structs because of their OO limitations and the fact that they're not nullable. There are however several structs in .Net : DateTime, int, float etc...

Comments

3

You can't do this. The reason is that structs are value types. The default constructor of a struct is a parameterless constructor that initializes all fields to their default value. You don't have control over this constructor because they are value types.

The best way to show this is e.g. through an array. Say you make an array of a a class type, e.g. new object[10]. The items of this array will be initialized to null. However, when you would make an array of structs, e.g. new information[10], the items of the array will be valid instances already. However, the constructor on these items won't have run and all fields will have been initialized to their empty values. In your case, this means that all fields will be null.

There are two solutions to this. The first solution is to create a factory method, e.g.:

public static information CreateNew()
{
    var result = new information();
    result.scoreList = new scores[10];
    return result;
}

This will work. You just create an instance with information.CreateNew() instead of new information(), and you will have an initialized information. However, a far more easy solution will be to just use a class instead.

Comments

0

There are three ways to have a structure behave as a value-type array of structs:

  • Use unsafe code to include one or more fixed arrays of primitives within your structure; have your indexed get/put accessors assemble a structure out of information stored in those arrays. For example, if you wanted to behave like an array of Point, one could have a fixed array for all the X coordinates and a fixed array for all the Y coordinates, and then have the this[int] getter construct a Point by combining an X and Y value, and the this[int] setter store the X and Y values from the passed-in point.
  • Have multiple fields of your struct type, and have the this[int] getter read from one of them and have the this[int] setter write to one of them. There are ways by which this can be made not too horribly inefficient, but it's still rather icky.
  • Have the structure hold a private array of the appropriate structure type. The get and set accessors should look something like:

    T[] _array;
    T this[int index] {
    get {
      T[] temp_array = _array;
      if (temp_array == null) return default(T);
      return temp_array[index];
    }
    set {
      do
      {
        T[] was_array[] = _array;
        T[] new_array = (temp_array == null) ? new T[size] : (T[])(temp_array.Clone());
        temp_array[index] = value;
      } while (System.Threading.Interlocked.CompareExchange(ref _array, new_array, was_array) !=
        was_array);
    }};
    

    This approach will allow the get indexer to run faster than would be possible with the second approach (and probably the first as well), and unlike the first approach it will work with generic types. The primary weakness with this approach is that every time its set accessor is run it must make a new copy of the array. If writes are much less frequent than reads, however, that might not be a problem. Incidentally, as written, the code should be fully thread-safe--something which is possible with mutable structures, but not possible with structures that pretend to be immutable.

  • Comments

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.