如何引用结构体内部的实例?

问题描述 投票:0回答:3

例如,假设我想制作一个遗传学模拟器,并且我有一个非常简单的结构

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

    person father;
    person mother;
}

这样我以后就可以用 Joey.father.haircolor 来引用 Joey 父母的头发颜色?我不断收到错误:

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

使用课程是我唯一的选择吗?为了速度起见,我更喜欢使用结构体,因为它都是数据,但如果没有其他选择,我显然可以只使用类。

c# struct
3个回答
6
投票

出于多种原因,您的类型 Person 应该是一个类:

  • 结构不能自引用
  • 如果实例很小且通常寿命较短或通常嵌入其他对象中,则应考虑使用结构体。好像不是这样的。
  • 如果满足所有这些条件,则应考虑使用结构体: 1. 它在逻辑上表示像基元类型一样的单个值 2. 它的实例大小小于 16 字节 3. 它是不可变的 4. 它不必经常装箱。事实并非如此。
  • 如果使用结构体,两个人不能共享同一个父亲,因为变量是按值传递的。这会产生糟糕的设计
  • 您对速度感兴趣,但使用类比结构更快,因为变量是通过引用而不是值传递的

0
投票

Struct 不能自引用,因为这会创建无限递归定义。您唯一的选择是使用课程。


0
投票

这只能通过 C# 中的不安全(非托管)代码实现。

C(不是 C#)结构中当然可以引用相同的类型:

#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);
}

但是在 C# 中,托管代码是不可能的:

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

    public string Name { get; set; }

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

然而,在 C# 中使用非托管代码是可能的:

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; }
}
© www.soinside.com 2019 - 2024. All rights reserved.