在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
复制到局部变量进行更改?
有没有办法做到这一点,而无需将整个基础复制到局部变量进行更改?
不,因为Nullable<T>
不提供对底层价值字段的直接访问。你不能“就地”修改它。
当你使用可变结构时,有各种各样的小问题。我强烈建议你尽可能使用类或不可变结构,以避免这些极端情况。
坦率地说,这里的主要错误几乎可以肯定:拥有一个可变结构。现在,有些情况下可变结构是有意义的,但这些情况很窄,而且这几乎肯定不是其中之一。
坦率地说,如果你停止这样做,你的代码将更容易合理化;使用最近的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;
对于这个“问题”,可能有许多可能的修复,具体取决于您的设计和要求的其余部分......例如:
public struct Tombstone
{
public Slab mainSlab;
public Slab basing;
public bool hasBasing => basing.sizeM != null;
//more...
}
说实话,我从不使用Nullables ...可以为Nullable值类型,接下来是什么,全局rvalues?