在 C# 中为可空结构的成员赋值
Assigning value to member of nullable struct in C#
在 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...
}
现在,我要修改baseing的成员:
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
如果我对不可为 null 的 mainSlab
执行相同操作,它会起作用。有没有办法在不将整个 basing
复制到局部变量进行更改的情况下执行此操作?
Is there a way to do this without copying the whole basing to a local variable for changes?
否,因为 Nullable<T>
不提供对基础值字段的直接访问。你不能修改它 "in place".
当你使用可变结构时,像这样的小问题有很多。我强烈建议您尽可能使用 类 或不可变结构,以避免这些极端情况。
坦率地说,这里的主要错误几乎可以肯定是:具有可变结构。现在,有 可变结构有意义的场景,但这些场景狭窄,这几乎肯定不是其中之一。
坦率地说,如果您停止这样做,您的代码将更容易合理化;使用最近的 C#,您甚至可以使用 readonly struct
来帮助执行此操作(并使用 in
获得更好的行为):
public readonly struct Slab
{ public readonly float[] sizeM;
public readonly string textureSrc;
//more members, not relevant here...
}
(我个人也会考虑属性而不是 public 字段,但这是一个单独的问题)
那么很明显你只能赋值整个对象:
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;
此 "problem" 可能有许多可能的修复方法,具体取决于您的其余设计和要求...例如:
public struct Tombstone
{
public Slab mainSlab;
public Slab basing;
public bool hasBasing => basing.sizeM != null;
//more...
}
老实说,我从不使用可空值...可空值类型,下一步是什么,全局右值?
在 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...
}
现在,我要修改baseing的成员:
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
如果我对不可为 null 的 mainSlab
执行相同操作,它会起作用。有没有办法在不将整个 basing
复制到局部变量进行更改的情况下执行此操作?
Is there a way to do this without copying the whole basing to a local variable for changes?
否,因为 Nullable<T>
不提供对基础值字段的直接访问。你不能修改它 "in place".
当你使用可变结构时,像这样的小问题有很多。我强烈建议您尽可能使用 类 或不可变结构,以避免这些极端情况。
坦率地说,这里的主要错误几乎可以肯定是:具有可变结构。现在,有 可变结构有意义的场景,但这些场景狭窄,这几乎肯定不是其中之一。
坦率地说,如果您停止这样做,您的代码将更容易合理化;使用最近的 C#,您甚至可以使用 readonly struct
来帮助执行此操作(并使用 in
获得更好的行为):
public readonly struct Slab
{ public readonly float[] sizeM;
public readonly string textureSrc;
//more members, not relevant here...
}
(我个人也会考虑属性而不是 public 字段,但这是一个单独的问题)
那么很明显你只能赋值整个对象:
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;
此 "problem" 可能有许多可能的修复方法,具体取决于您的其余设计和要求...例如:
public struct Tombstone
{
public Slab mainSlab;
public Slab basing;
public bool hasBasing => basing.sizeM != null;
//more...
}
老实说,我从不使用可空值...可空值类型,下一步是什么,全局右值?