C# 在C中为可空结构的成员赋值#

C# 在C中为可空结构的成员赋值#,c#,nullable,value-type,C#,Nullable,Value Type,在C#中,我有这样一个结构: public struct Slab { public float[] sizeM; public string textureSrc; //more members, not relevant here... } public struct Tombstone { public Slab mainSlab; public Slab? basing; //more... } 还有一个是这样的: public struct

在C#中,我有这样一个结构:

public struct Slab
{   public float[] sizeM;
    public string textureSrc;
    //more members, not relevant here...
}
public struct Tombstone
{   public Slab mainSlab;
    public Slab? basing;
    //more...
}
还有一个是这样的:

public struct Slab
{   public float[] sizeM;
    public string textureSrc;
    //more members, not relevant here...
}
public struct Tombstone
{   public Slab mainSlab;
    public Slab? basing;
    //more...
}
现在,我要修改的成员是:

uiState[0].stone.basing.Value.sizeM[2] = Int32.Parse(breadthField.Value) / 100.0f;
uiState[0].stone.basing.Value.textureSrc = fileName;
uiState[0]。石头的类型为
Tombstone

这两个调用中的第一个可以正常工作,因为我只是在
中更改数组的一个成员,而不是数组本身。然而,第二位投诉:

Cannot modify the return value of 'Slab?.Value' because it is not a variable
如果我对不可为空的
mainstab
执行相同的操作,则它会起作用。有没有一种方法可以在不将整个
基值
复制到局部变量以进行更改的情况下执行此操作

有没有一种方法可以做到这一点,而无需将整个变量复制到局部变量以进行更改

否,因为
Nullable
不提供对基础值字段的直接访问。您不能“就地”修改它

当您使用可变结构时,会出现各种各样的小问题。我强烈建议您尽可能使用类或不可变结构,以避免出现这种情况

有没有一种方法可以做到这一点,而无需将整个变量复制到局部变量以进行更改

否,因为
Nullable
不提供对基础值字段的直接访问。您不能“就地”修改它


当您使用可变结构时,会出现各种各样的小问题。我强烈建议您尽可能使用类或不可变结构,以避免这些极端情况。

坦率地说,这里的主要错误几乎肯定是:使用可变结构。现在,有些场景中可变结构是有意义的,但这些场景很窄,几乎可以肯定这不是其中之一

坦率地说,如果您停止这样做,您的代码将更容易合理化;使用最新的C#,您甚至可以使用
readonly struct
来帮助实现这一点(并使用
中的
获得更好的行为):

(我个人也会考虑属性而不是公共字段,但这是一个单独的问题)

很明显,您只能指定整个对象:

Slab? foo = ...
... some logic
foo = new Slab(size, textureSource); // perhaps taking new values from the old
唯一的其他选择是基本上做同样的事情:


坦率地说,这里的主要错误几乎是肯定的:具有可变结构。现在,有些场景中可变结构是有意义的,但这些场景很窄,几乎可以肯定这不是其中之一

坦率地说,如果您停止这样做,您的代码将更容易合理化;使用最新的C#,您甚至可以使用
readonly struct
来帮助实现这一点(并使用
中的
获得更好的行为):

(我个人也会考虑属性而不是公共字段,但这是一个单独的问题)

很明显,您只能指定整个对象:

Slab? foo = ...
... some logic
foo = new Slab(size, textureSource); // perhaps taking new values from the old
唯一的其他选择是基本上做同样的事情:


这个“问题”可能有很多可能的修复方法,这取决于您的其他设计和需求。。。例如:

public struct Tombstone
{
  public Slab mainSlab;
  public Slab basing;
  public bool hasBasing => basing.sizeM != null;
  //more...
}

老实说,我从不使用空值。。。可空值类型、下一步是什么、全局右值?

此“问题”可能有许多可能的修复方法,具体取决于您的其他设计和要求。。。例如:

public struct Tombstone
{
  public Slab mainSlab;
  public Slab basing;
  public bool hasBasing => basing.sizeM != null;
  //more...
}

老实说,我从不使用空值。。。可为空的值类型,下一步是什么,全局右值?

也许我应该,你是对的。我的经验法则是,如果你想要多模态,就使用类,否则就使用结构,但这条规则可能只适用于D,而不适用于C。如果你是对的,而且有人没有想出主意,我会把你的答案标记为接受。@dukc:在C#中,这绝对不是一个好规则。(此外,公共字段在C#中几乎总是一个坏主意,因为你失去了封装的机会。)有关何时使用类和何时使用结构的更多详细信息,请参阅。“我的经验法则是,如果你想要多模态,就使用类,否则就使用结构”-是的,这是一个糟糕的主意,它会咬你;你会惊奇地发现,人们经常用这种枪打自己的脚。可变结构是有效的,但它们绝对不是“轻量级类,因为当您不需要虚拟方法时”的同义词。也许我应该,您是对的。我的经验法则是,如果你想要多模态,就使用类,否则就使用结构,但这条规则可能只适用于D,而不适用于C。如果你是对的,而且有人没有想出主意,我会把你的答案标记为接受。@dukc:在C#中,这绝对不是一个好规则。(此外,公共字段在C#中几乎总是一个坏主意,因为你失去了封装的机会。)有关何时使用类和何时使用结构的更多详细信息,请参阅。“我的经验法则是,如果你想要多模态,就使用类,否则就使用结构”-是的,这是一个糟糕的主意,它会咬你;你会惊奇地发现,人们经常用这种枪打自己的脚。可变结构是有效的,但它们绝对不是“轻量级类,因为当您不需要虚拟方法时”的同义词有趣的事实:我的代码是
uiState[0]
的原因是
uiState
也是一种值类型,我需要一个指向它的指针。嘿,我默认喜欢值语义!我也可以对基于
做同样的操作,但我想这次我会复制结构。@dukc您使用的是最新版本的C#吗?“ref locals”是一个东西-你可以做
ref-UIState x=ref-UIState[0]
,使
x
成为托管引用(技术上是托管指针);如果这里所有的
.whatever
都是结构中的字段,那么也可以使用“内部指针”。没有完整的代码很难说,但您可能可以创建一个
ref Slab
,它是指向
uiState[0].stone.based的内部指针!但是,您不能创建指向
可空的
字段的内部指针,因为它没有公开;但是:
ref-var-baseding=ref-uiState[0].stone.baseding有趣的事实:我的代码之所以是
uiState[0]
是因为
uiState