我正在尝试用 C# 构建一个模拟。 我想将模型本身作为一个结构来处理。模型内部有很多元素(我将它们称为单元格,考虑到元素也指我程序中的化学元素,这很令人困惑) 每个 cel 都是一个结构。里面的数据类型之一是 float 组。
下面是我写的代码:
struct Model
{
//model consists of an array of cells
public Cel[] cel = new Cel[100];
public Model() { }
}
struct Cel
{
public float[] n = new float[3];
public Cel() { }
}
class Programs
{
static int Main()
{
Model model = new Model();
model.cel[1].n[1] = 0.2f;
Console.WriteLine(model.cel[1].n[1]);
//prevent console from closing
Console.ReadLine();
return 0;
}
}
当我运行它时,它会编译,但会给出一条消息:
System.NullReferenceException:“对象引用未设置为对象的实例。”
model.cel[].n 为空。在第 24 行
model.cel[1].n[1] = 0.2f;
我认为这是执行此操作的合乎逻辑的方式,并且希望有一个解决方案使其发挥作用。 如果这不是这样做的方法,有人可以指出我正确的方向吗?
感谢您的帮助。
最佳答案
数组创建不会初始化数组内部的每个元素——它们都是默认值;你可以做这样的事情:
public Cel[] cel;
public Model() {
cel = new Cel[100];
for (int i = 0; i < cel.Length; i++)
{
cel[i] = new Cel();
}
}
手动初始化每个,但是...老实说,我不确定这是一个很好的结果。特别是,在 Cel
结构中包含 3 个谨慎的 float
字段而不是 float[3]
将是一种更典型的实现,可能会使模型
一个类
。您通常还应该对公共(public)字段和可变结构非常谨慎。
可能是这样的:
sealed class Model
{
//model consists of an array of cells
private readonly Cel[] cel = new Cel[100];
public ref Cel this[int index] => ref cel[index];
}
readonly struct Cel
{
public float X { get; }
public float Y { get; }
public float Z { get; }
public Cel(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public Cel WithX(float x) => new Cel(x, Y, Z);
public Cel WithY(float y) => new Cel(X, y, Z);
public Cel WithZ(float z) => new Cel(X, Y, z);
}
class Programs
{
static int Main()
{
Model model = new Model();
ref var cel = ref model[1];
cel = cel.WithY(0.2f);
Console.WriteLine(model[1].Y);
//prevent console from closing
Console.ReadLine();
return 0;
}
}
或使用固定缓冲区和跨度破解:
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
sealed class Model
{
//model consists of an array of cells
private readonly Cel[] cel = new Cel[100];
public ref Cel this[int index] => ref cel[index];
}
unsafe struct Cel
{
private fixed float n[3];
public float X => n[0];
public float Y => n[1];
public float Z => n[2];
public Span<float> N
{
get
{
fixed (float* ptr = n)
{
return MemoryMarshal.CreateSpan(ref Unsafe.AsRef<float>(ptr), 3);
}
}
}
public Cel(float x, float y, float z)
{
fixed (float* ptr = n)
{
ptr[0] = x;
ptr[1] = y;
ptr[2] = z;
}
}
private Cel(in Cel from, int index, float value)
{
this = from;
n[index] = value;
}
public Cel WithX(float x) => new Cel(this, 0, x);
public Cel WithY(float y) => new Cel(this, 1, y);
public Cel WithZ(float z) => new Cel(this, 2, z);
}
class Programs
{
static int Main()
{
Model model = new Model();
ref var cel = ref model[1];
cel = cel.WithY(0.2f);
Console.WriteLine(model[1].Y);
Console.WriteLine();
foreach (var val in model[1].N) // and iterate via span
{
Console.WriteLine(val);
}
//prevent console from closing
Console.ReadLine();
return 0;
}
}
关于c# 嵌套结构中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73277991/