Daymare
Daymare

Reputation: 69

How to reference an instance of a struct inside of itself?

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.

Upvotes: 1

Views: 6105

Answers (2)

Aaron Thomas
Aaron Thomas

Reputation: 5281

This is only possible through unsafe (unmanaged) code in C#.

In C (not C#) structs certainly may reference to the same type:

#include <stdio.h>

struct my_struct {
    int id;
    struct my_struct *parent;
};

int main() {
    struct my_struct parent_struct = {
            .id = 0
    };

    struct my_struct *parent_pointer = &parent_struct;

    struct my_struct child_struct = {
            .id = 1, .parent = parent_pointer
    };

    printf("Child's parent id is %d", child_struct.parent->id);
}

But in C#, it is not possible with managed code:

public struct MyStruct
{
    public MyStruct(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    // does not compile
    public MyStruct Parent { get; set; }
}

Yet it is possible in C# with unmanaged code:

internal class Program
{
    private static void Main(string[] args)
    {
        unsafe
        {
            var parent = new MyStruct("parent");
            var child = new MyStruct("child");
            child.Parent = &parent;

            var parentName = child.Parent->Name;
            Console.WriteLine(parentName);
        }
    }
}

public struct MyStruct
{
    public MyStruct(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    public unsafe MyStruct* Parent { get; set; }
}

Upvotes: 0

gentiane
gentiane

Reputation: 6835

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

Upvotes: 6

Related Questions