C# 自动属性和结构不混合?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/420433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Automatic Properties and Structures Don't Mix?
提问by Mike Rosenblum
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:
以下结构,使用 int 字段是完全合法的:
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.
返回的错误是“在分配所有字段之前不能使用‘this’对象”。我知道这是结构的标准过程:必须从结构的构造函数中直接分配任何属性的支持字段(而不是通过属性的 set 访问器)。
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.)
(注意 VB.NET 不会有这个问题,因为在 VB.NET 中所有字段在第一次创建时都会自动初始化为 0/null/false。)
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?
在 C# 中对结构使用自动属性时,这似乎是一个不幸的限制。从概念上思考,我想知道这是否不是一个合理的地方,允许在结构的构造函数中调用属性集访问器的异常,至少对于自动属性?
This is a minor issue, almost an edge-case, but I was wondering what others thought about this...
这是一个小问题,几乎是边缘情况,但我想知道其他人对此有何看法......
采纳答案by Marc Gravell
From C# 6 onward: this is no longer a problem
从 C# 6 开始:这不再是问题
Becore C# 6, you need to call the default constructor for this to work:
Becore C# 6,你需要调用默认构造函数才能工作:
public MyStruct(int size) : this()
{
Size = size;
}
A bigger problem here is that you have a mutable struct. This is nevera good idea. I would make it:
这里更大的问题是您有一个可变结构。这从来都不是一个好主意。我会做到:
public int Size { get; private set; }
Not technicallyimmutable, but close enough.
在技术上不是一成不变的,但足够接近。
With recent versions of C#, you can improve on this:
使用最新版本的 C#,您可以改进这一点:
public int Size { get; }
This can now onlybe assigned in the constructor.
这现在只能在构造函数中分配。
回答by Stormenet
You can fix this by first calling the default constructor:
您可以通过首先调用默认构造函数来解决此问题:
struct MyStruct
{
public MyStruct(int size) : this()
{
this.Size = size; // <-- now works
}
public int Size { get; set; }
}
回答by Daniel Fortunov
Another obscure work-around to this problem is one spotted in the temporary Tuple
class in the Managed Extensibility Framework(via Krzysztof Ko?mic):
这个问题的另一个模糊解决方法是Tuple
在托管可扩展性框架的临时类中发现的(通过Krzysztof Ko?mic):
public struct TempTuple<TFirst, TSecond>
{
public TempTuple(TFirst first, TSecond second)
{
this = new TempTuple<TFirst, TSecond>(); // Kung fu!
this.First = first;
this.Second = second;
}
public TFirst First { get; private set; }
public TSecond Second { get; private set; }
(Full source code from Codeplex: Tuple.cs)
(来自 Codeplex 的完整源代码:Tuple.cs)
I also note that the documentation for CS0188has been updated to add:
我还注意到CS0188的文档已更新以添加:
If you see this error when trying to initialize a property in a struct constructor, the solution is to change the constructor parameter to specify the backing field instead of the property itself. Auto-implemented properties should be avoided in structs because they have no backing field and therefore cannot be initialized in any way from the constructor.
如果您在 struct 构造函数中尝试初始化属性时看到此错误,解决方案是更改构造函数参数以指定支持字段而不是属性本身。应该避免在结构中使用自动实现的属性,因为它们没有支持字段,因此不能从构造函数以任何方式初始化。
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.
所以我认为这意味着官方指导是当您遇到这个问题时在结构中使用旧式属性,这可能比目前探索的其他两个替代方案中的任何一个都不那么晦涩(也更易读)。