我注意到在Microsoft.Xna.Framework.Rectangle
struct
中,有很多属性只是public int Bottom { get; }
或public Point Center { get; }
。对于我的生活,我无法弄清楚这里发生了什么。我已经尝试在我自己的一些结构中复制它,但我无法弄清楚如何在没有set;
关键字的情况下给它一个值。 Rectangle
struct
对{get;}
做了什么?
答案 0 :(得分:1)
这意味着以后无法设置属性为您提供访问权限的基础值..您只能"得到"潜在价值。
当您实例化Rectangle
时,您必须传递一些值:
public Rectangle (int x, int y, int width, int height)
我的猜测(不看源代码)是属性值(Center
,Bottom
等)都在构造函数中设置。您以后无法更改它们。要么寻找另一个要设置的属性(即X
或Y
),要么根据现有属性创建新的Rectangle
。< / p>
var newRect = new Rectangle(oldRect.X, oldRect.Y, oldRect.Width, oldRect.Height);
为了比较,这里是来自System.Drawing.Rectangle
结构的源代码的一部分,这可能与您正在处理的内容非常接近。请注意,您可以通过构造函数设置某些值,然后将这些值存储在私有变量中,并且可以访问(但在某些情况下只能可更改)。
public struct Rectangle
{
public static readonly Rectangle Empty = new Rectangle();
private int x;
private int y;
private int width;
private int height;
public Rectangle(int x, int y, int width, int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int X
{
get { return x; }
set { x = value; }
}
public int Left
{
get { return X; }
}
public int Y
{
get { return y; }
set { y = value; }
}
public int Top
{
get { return Y; }
}
...
...
}
答案 1 :(得分:1)
Rectangle.Bottom
没有设置的原因是因为它是一个计算值Top + Height
。如果你愿意,那你想发生什么?改变y位置?改变高度?不可能知道。因此,您必须自行决定并根据您的实际需要更改Top
或Height
。
属性的概念不仅仅是拥有变量并设置或获取它。如果它是我们可以使用公共变量,那就是它。相反,我们的想法是允许验证和计算属性。
public int Bottom
{
get { return Top + Height; }
}
正如您所看到的,没有必要将其设置为任何内容,因为它将根据其他值推断其值。
(当然在内部很可能不会使用其他属性,而是由于性能而使用实际变量)
答案 2 :(得分:0)
请考虑以下事项:
private int myVar;
public int MyProperty
{
get { return myVar; }
}
在这里,您可以看到一个直接从Visual Studio的C#片段中获取的示例,其中显示了如何实现get-only属性。您需要设置backing field,但无法通过该属性进行设置,因为此属性被称为a read-only property或a property with no setter method。这些属性的目的是制作关于您的对象的合同声明&#34;此属性无法设置。&#34;
这类似于拥有私有setter,但是,您不能在接口定义中强制执行访问修饰符。因此,在定义数据协定和对象接口时,此语法用于特定目的,也就是说&#34;此属性不能通过契约设置,并且任何子类都不会将公共setter作为此合同的一部分公开。&# 34;
另外,you can circumvent access modifiers using reflection,但这不是常见的情况(99%的.NET开发人员可能没有意识到这一点。)
通常backing fields通过构造函数,反射或对象初始化的一部分设置。
这也是核心语法,它构成了现代句法糖的基础。请考虑以下属性定义:
public int MyProperty { get; set; }
这完全是语法糖,实际上对C#1.0编译器无效。今天在编译时,backing field为generated on your behalf。因此,以下语法仅对接口定义有效(否则它将永远不会返回有意义的值。)
public int MyProperty { get; }
以上是使用较新的read-only property语法创建auto-property的(无效)尝试。
参考文献: