1

For example, say I wanted to make a genetics simulator and I had this very simple struct

public struct person{
    string name;
    int age;
    string hairColor; 

    person father;
    person mother;
}

so that later I could reference the person Joey's parent's hair color with Joey.father.haircolor? I keep getting error:

Struct Member 'person.father' of type 'person' causes a cycle in the struct layout

Is my only option to use a class? For the sake of speed I'd prefer to use a struct since it's all data, but if there's no alternative I can obviously just use a class.

Daymare
  • 69
  • 2
  • 5
  • 6
    I think you've misunderstood how structs work - particularly given your "since it's all data". What do you mean by that? What do you think the difference between a struct and a class is? – Jon Skeet Jun 07 '16 at 19:47
  • What @JonSkeet is alluding to is that once you understand the difference between a class and a struct, the problem at hand will be very apparent: https://msdn.microsoft.com/en-us/library/ms173109.aspx?f=255&MSPPError=-2147217396 – GEEF Jun 07 '16 at 19:49
  • I was under the impression from what I've read that structs and classes are close to the same thing, but structs should be used when it's more of a collection of data – Daymare Jun 07 '16 at 19:52
  • 1
    You're not entirely wrong. However, as stated below, that structs are of a 'set memory size', and a self-reference would allow it to grow infinitely. (see http://stackoverflow.com/questions/9296251/cycle-in-the-struct-layout-that-doesnt-exist) – GEEF Jun 07 '16 at 19:53
  • 1
    Also, aren't you starting to miss C++ pointers? ;) – GEEF Jun 07 '16 at 19:55
  • You should basically never use a struct when you have a collection of data. You should use a stuct when you have something that is conceptually a single value, and this is not. – Servy Jun 07 '16 at 20:00
  • Here are three rules: (1) A struct has a size. (2) The size of a struct is never less than the sum of the sizes of all instance fields. (3) A reference has a fixed size regardless of its contents. So, answer me this: what is the size of your struct? (Rule 2 is actually a slight lie, but for the purposes of this discussion you can treat it as true.) – Eric Lippert Jun 07 '16 at 21:01

2 Answers2

6

Your type Person should be a class for multiple reasons :

  • a struct can not self reference
  • a struct should be considered if the instance will be small and commonly short-lived or are commonly embedded in other objects. It does not seem to be the case.
  • a struct should be considered if all these conditions are met : 1. it logically represents a single value like primitive types 2. it has an instance size under 16 bytes 3.iIt is immutable 4. It will not have to be boxed frequently. It is not the case.
  • if you use a struct, two persons could not share the same father as the variable are passed by value. This will produce a bad design
  • you are interested by speed but usage of a class is faster than a struct, as variable are passed by reference instead of by value
gentiane
  • 6,715
  • 3
  • 23
  • 34
  • 2
    That's a nice answer indeed. – Rahul Jun 07 '16 at 20:05
  • 1
    Your last point needs to be reworded. A variable is passed by value, and a struct is also passed by value. A class is passed by reference. There's little performance difference access either one, since using a register to access the heap vs the stack is very much similar (just different registers). Setting very large struct values many times though can be a bit slower than setting references. In fact, a struct too large will most likely end up in the heap, and not the stack. – James Wilkins Aug 22 '18 at 08:01
0

Struct cannot self-reference, as that would create an infinitely recursive definition. Your only option is to use a class.

Paul-Jan
  • 16,746
  • 1
  • 63
  • 95
  • 2
    How would this argument not apply to classes? – mireazma Jan 16 '18 at 21:55
  • 1
    @mireazma classes can be null so the recursion ends somewhere (or creates a loop of references, which is fine as it requires a finite amount of memory). Structs cannot be null and can't create a loop that terminates somewhere because every struct type field holds its own copy of the struct. – Mike Marynowski Jan 31 '18 at 08:16
  • 1
    "that would create an infinitely recursive definition" - is not true. If I add a value in the struct to track state, then I could know where "null" is. "null" could also be defined a simply == 0 (doesn't have to be a reference type, and in fact, the computer sees 0's for null pointers). If the struct actually wraps a pointer, then there is a null value. You can also overload == on structs, and other operations, so yes, it could == null if designed to do so. – James Wilkins Aug 22 '18 at 08:10