Cycle in the struct layout that doesn't exist

It's not legal to have a struct that contains itself as a member. This is because a struct has fixed size, and it must be at least as large as the sum of the sizes of each of its members. Your type would have to have 8 bytes for the two floats, at least one byte to show whether or not info is null, plus the size of another info. This gives the following inequality:

 size of info >= 4 + 4 + 1 + size of info

This is obviously impossible as it would require your type to be infinitely large.

You have to use a reference type (i.e. class). You can make your class immutable and override Equals and GetHashCode to give value-like behaviour, similar to the String class.


The reason why this creates a cycle is that Nullable<T> is itself a struct. Because it refers back to info you have a cycle in the layout (info has a field of Nullable<info> and it has a field of info) . It's essentially equivalent to the following

public struct MyNullable<T> {
  public T value;
  public bool hasValue;
}

struct info { 
  public float a, b;
  public MyNullable<info> next;
}

The real problem is on this line:

public info? c;

Since this is a struct, C# needs to know the inner info/s layout before it could produce outer info's layout. And the inner info includes an inner inner info, which in turn includes an inner inner inner info, and so on. The compiler cannot produce a layout because of this circular reference issue.

Note: info? c is a shorthand for Nullable<info> which is itself a struct.