自动属性和结构不能混合?
在回答这篇文章时,我遇到了一些小结构,意外地遇到了以下结构:
以下结构,使用 int 字段是完全合法的:
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Legal assignment.
}
public int Size;
}
但是,使用自动属性的以下结构无法编译:
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Compile-Time Error!
}
public int Size{get; set;}
}
返回的错误是“在将 'this' 对象的所有字段分配给之前,无法使用该对象”。 我知道这是结构的标准过程:任何属性的支持字段都必须从结构的构造函数中直接分配(而不是通过属性的设置访问器)。
解决方案是使用显式支持字段:(
struct MyStruct
{
public MyStruct(int size)
{
_size = size;
}
private int _size;
public int Size
{
get { return _size; }
set { _size = value; }
}
}
请注意,VB.NET 不会出现此问题,因为在 VB.NET 中,所有字段在首次创建时都会自动初始化为 0/null/false。)
这似乎是一个不幸的情况。在 C# 中使用带有结构的自动属性时的限制。 从概念上思考,我想知道这是否是一个合理的地方,允许在结构的构造函数中调用属性集访问器,至少对于自动属性来说是这样?
这是一个小问题,几乎是一个边缘情况,但我想知道其他人对此有何看法......
Kicking around some small structures while answering this post, I came across the following unexpectedly:
The following structure, using an int field is perfectly legal:
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Legal assignment.
}
public int Size;
}
However, the following structure, using an automatic property does not compile:
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Compile-Time Error!
}
public int Size{get; set;}
}
The error returned is "The 'this' object cannot be used before all of its fields are assigned to". I know that this is standard procedure for a struct: the backing field for any property must be assigned directly (and not via the property's set accessor) from within the struct's constructor.
A solution is to use an explicit backing field:
struct MyStruct
{
public MyStruct(int size)
{
_size = size;
}
private int _size;
public int Size
{
get { return _size; }
set { _size = value; }
}
}
(Note that VB.NET would not have this issue, because in VB.NET all fields are automatically initialized to 0/null/false when first created.)
This would seem to be an unfortunate limitation when using automatic properties with structs in C#. Thinking conceptually, I was wondering if this wouldn't be a reasonable place for there to be an exception that allows the property set accessor to be called within a struct's constructor, at least for an automatic property?
This is a minor issue, almost an edge-case, but I was wondering what others thought about this...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过首先调用默认构造函数来解决此问题:
You can fix this by first calling the default constructor:
此问题的另一个晦涩的解决方法是在 托管扩展性中的临时
Tuple
类中发现的解决方法框架(来自Krzysztof Koźmic ):(Codeplex 的完整源代码:Tuple.cs< /a>)
我还注意到 CS0188 的文档已更新加上:
我认为这意味着官方指导是在遇到这个问题时在结构中使用旧式属性,这可能比其他两个问题更不晦涩(并且更易读)迄今为止探索的替代方案。
Another obscure work-around to this problem is one spotted in the temporary
Tuple
class in the Managed Extensibility Framework (via Krzysztof Koźmic):(Full source code from Codeplex: Tuple.cs)
I also note that the documentation for CS0188 has been updated to add:
So I take that to mean that the official guidance is to use old-style properties in your structs when you run in to this problem, which is probably less obscure (and more readible) than either of the other two alternatives explored so far.
从 C# 6 开始:这不再是问题
在 C# 6 中,您需要调用默认构造函数才能使其工作:
这里更大的问题是您有一个可变结构。 这绝不是一个好主意。 我会做到:
技术上不是一成不变的,但足够接近。
使用最新版本的 C#,您可以对此进行改进:
现在只能在构造函数中进行赋值。
From C# 6 onward: this is no longer a problem
Becore C# 6, you need to call the default constructor for this to work:
A bigger problem here is that you have a mutable struct. This is never a good idea. I would make it:
Not technically immutable, but close enough.
With recent versions of C#, you can improve on this:
This can now only be assigned in the constructor.