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

时间:2018-06-29 09:34:54

标签: 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...
}

现在,我要修改基础成员:

uiState[0].stone.basing.Value.sizeM[2] = Int32.Parse(breadthField.Value) / 100.0f;
uiState[0].stone.basing.Value.textureSrc = fileName;

uiState[0].stone的类型为Tombstone

这两个调用中的第一个正确运行,因为我只是在basing中更改数组的成员,而不是数组本身。但是,第二个抱怨:

Cannot modify the return value of 'Slab?.Value' because it is not a variable

如果我对不可为空的mainSlab执行相同的操作,它将起作用。有没有办法将整个basing复制到本地变量以进行更改?

3 个答案:

答案 0 :(得分:2)

  

有没有一种方法可以将整个基础复制到本地变量中以进行更改?

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

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

答案 1 :(得分:2)

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

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

public readonly struct Slab
{   public readonly float[] sizeM;
    public readonly string textureSrc;
    //more members, not relevant here...
}

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

然后很明显,您只能分配整个对象:

Slab? foo = ...
... some logic
foo = new Slab(size, textureSource); // perhaps taking new values from the old

唯一的另一种选择是基本上无论如何都要做相同的事情

Slab? foo = ...
// ...
var innerVal = foo.GetValueOrDefault(); // or .Value if you've already null-checked
// ...
innerVal.textureSrc = ...
foo = innerVal;

答案 2 :(得分:0)

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

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

说实话,我从不使用Nullables ... Nullable值类型,接下来是全局右值吗?