我如何使用 属性 { get; }?
how do i use a property { get; }?
我注意到在 Microsoft.Xna.Framework.Rectangle
struct
中,有很多属性只是 public int Bottom { get; }
或 public Point Center { get; }
。我,对于我的生活,无法弄清楚这里发生了什么。我已经尝试在我自己的一些结构中复制它,但我不知道如何在没有 set;
关键字的情况下首先给它一个值。 Rectangle
struct
对 {get;}
做了什么?
这意味着 属性 允许您访问的基础值以后无法设置。您只能 "get" 基础值。
当你实例化一个Rectangle
时,你必须给它传递一些值:
public Rectangle (int x, int y, int width, int height)
我的猜测(没有查看源代码)是 属性 值(Center
、Bottom
等)都在构造函数中设置。你以后不能改变它们.. 要么寻找另一个 属性 来设置(即 X
或 Y
),要么基于现有的 Rectangle
创建一个新的 Rectangle
.
var newRect = new Rectangle(oldRect.X, oldRect.Y, oldRect.Width, oldRect.Height);
为了进行比较,这里是 System.Drawing.Rectangle
结构的一部分源代码,它可能与您正在处理的内容相当接近。请注意,您可以通过构造函数设置某些值,然后将其存储在私有变量中,并且可以访问(但在某些属性中只能 changeable)。
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; }
}
...
...
}
考虑以下几点:
private int myVar;
public int MyProperty
{
get { return myVar; }
}
在这里您可以看到一个示例,直接取自 Visual Studio 的 C# 片段,展示了如何实现只获取 属性。您需要设置backing field, but it cannot be done via the property because this property is said to be a read-only property or a property with no setter method。此类属性的目的是对您的对象作出合同声明"this property cannot be set."
这类似于私有 setter,但是,您不能在接口定义中强制使用访问修饰符。因此,这种语法在定义数据契约和对象接口时服务于特定目的,也就是说 "this property cannot be set, by contract, and no subclass may expose a public setter as part of this contract."
顺便说一句,you can circumvent access modifiers using reflection,但这并不常见(而且 99% 的 .NET 开发人员可能都没有意识到这一事实。)
通常 backing fields 通过构造函数、反射或作为对象初始化的一部分进行设置。
这也是核心语法,它构成了现代语法糖的基础。考虑以下 属性 定义:
public int MyProperty { get; set; }
这完全是语法糖,实际上对 C# 1.0 编译器无效。今天编译时一个backing field is generated on your behalf。因此,以下语法仅对接口定义有效(否则它永远不会 return 一个有意义的值。)
public int MyProperty { get; }
以上是创建 read-only property using the newer auto-property 语法的(无效)尝试。
参考文献:
- When should use Readonly and Get only properties
- Using a backing variable for getters and setters
- Is it possible to access backing fields behind auto-implemented properties?
- https://msdn.microsoft.com/en-us/library/bb384054.aspx
- https://msdn.microsoft.com/en-us/library/w86s7x04.aspx
Rectangle.Bottom
之所以没有集合是因为它是一个计算值,Top + Height
。如果你愿意设置它,你希望发生什么?改变y位置?改变高度?这是不可能知道的。因此,您必须自己决定并根据您的实际需要更改 Top
或 Height
。
属性的概念不仅仅是拥有一个变量并设置或获取它。如果是的话,我们可以只使用 public 变量,就是这样。相反,这个想法是允许验证和计算属性。
public int Bottom
{
get { return Top + Height; }
}
如您所见,无需将其设置为任何值,因为它会根据其他值推断其值。
(当然在内部它很可能不会使用其他属性,而是由于性能而使用实际变量)
我注意到在 Microsoft.Xna.Framework.Rectangle
struct
中,有很多属性只是 public int Bottom { get; }
或 public Point Center { get; }
。我,对于我的生活,无法弄清楚这里发生了什么。我已经尝试在我自己的一些结构中复制它,但我不知道如何在没有 set;
关键字的情况下首先给它一个值。 Rectangle
struct
对 {get;}
做了什么?
这意味着 属性 允许您访问的基础值以后无法设置。您只能 "get" 基础值。
当你实例化一个Rectangle
时,你必须给它传递一些值:
public Rectangle (int x, int y, int width, int height)
我的猜测(没有查看源代码)是 属性 值(Center
、Bottom
等)都在构造函数中设置。你以后不能改变它们.. 要么寻找另一个 属性 来设置(即 X
或 Y
),要么基于现有的 Rectangle
创建一个新的 Rectangle
.
var newRect = new Rectangle(oldRect.X, oldRect.Y, oldRect.Width, oldRect.Height);
为了进行比较,这里是 System.Drawing.Rectangle
结构的一部分源代码,它可能与您正在处理的内容相当接近。请注意,您可以通过构造函数设置某些值,然后将其存储在私有变量中,并且可以访问(但在某些属性中只能 changeable)。
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; }
}
...
...
}
考虑以下几点:
private int myVar;
public int MyProperty
{
get { return myVar; }
}
在这里您可以看到一个示例,直接取自 Visual Studio 的 C# 片段,展示了如何实现只获取 属性。您需要设置backing field, but it cannot be done via the property because this property is said to be a read-only property or a property with no setter method。此类属性的目的是对您的对象作出合同声明"this property cannot be set."
这类似于私有 setter,但是,您不能在接口定义中强制使用访问修饰符。因此,这种语法在定义数据契约和对象接口时服务于特定目的,也就是说 "this property cannot be set, by contract, and no subclass may expose a public setter as part of this contract."
顺便说一句,you can circumvent access modifiers using reflection,但这并不常见(而且 99% 的 .NET 开发人员可能都没有意识到这一事实。)
通常 backing fields 通过构造函数、反射或作为对象初始化的一部分进行设置。
这也是核心语法,它构成了现代语法糖的基础。考虑以下 属性 定义:
public int MyProperty { get; set; }
这完全是语法糖,实际上对 C# 1.0 编译器无效。今天编译时一个backing field is generated on your behalf。因此,以下语法仅对接口定义有效(否则它永远不会 return 一个有意义的值。)
public int MyProperty { get; }
以上是创建 read-only property using the newer auto-property 语法的(无效)尝试。
参考文献:
- When should use Readonly and Get only properties
- Using a backing variable for getters and setters
- Is it possible to access backing fields behind auto-implemented properties?
- https://msdn.microsoft.com/en-us/library/bb384054.aspx
- https://msdn.microsoft.com/en-us/library/w86s7x04.aspx
Rectangle.Bottom
之所以没有集合是因为它是一个计算值,Top + Height
。如果你愿意设置它,你希望发生什么?改变y位置?改变高度?这是不可能知道的。因此,您必须自己决定并根据您的实际需要更改 Top
或 Height
。
属性的概念不仅仅是拥有一个变量并设置或获取它。如果是的话,我们可以只使用 public 变量,就是这样。相反,这个想法是允许验证和计算属性。
public int Bottom
{
get { return Top + Height; }
}
如您所见,无需将其设置为任何值,因为它会根据其他值推断其值。
(当然在内部它很可能不会使用其他属性,而是由于性能而使用实际变量)