如何使用属性{get;}

本文关键字:get 何使用 属性 | 更新日期: 2023-09-27 17:50:53

我注意到,在Microsoft.Xna.Framework.Rectangle struct中,有很多属性只是public int Bottom { get; }public Point Center { get; }。I、 我一辈子都搞不清楚这里发生了什么。我已经尝试在我自己的一些结构中复制它,但如果没有set;关键字,我一开始就不知道如何给它一个值。Rectangle struct{get;}做了什么?

如何使用属性{get;}

Rectangle.Bottom没有集合的原因是因为它是一个计算值Top + Height。如果你设定了这个,你希望发生什么?更改y位置?更改高度?不可能知道。因此,您必须自己决定,并根据实际需要更改TopHeight

属性的概念不仅仅是有一个变量并设置或获取它。如果是这样,我们可以使用公共变量,仅此而已。相反,它的概念是允许验证和计算属性。

public int Bottom
{
  get { return Top + Height; }
}

正如您所看到的,没有必要将其设置为任何值,因为它将根据其他值推断其值。

(当然,在内部,它很可能不会使用其他属性,而是由于性能的原因使用实际变量(

这意味着属性允许您访问的基础值以后不能设置。您只能"获取"基础值。

当您实例化Rectangle时,您必须向它传递几个值:

public Rectangle (int x, int y, int width, int height)

我的猜测(不看源代码(是,属性值(CenterBottom等(都是在构造函数中设置的。以后不能更改它们。要么查找另一个要设置的属性(即XY(,要么在现有属性的基础上创建一个新的Rectangle

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; }
    }
    ...
    ...
}

考虑以下内容:

    private int myVar;
    public int MyProperty
    {
        get { return myVar; }
    }

在这里,您可以看到一个直接取自VisualStudio的C#代码段的示例,它显示了如何实现get-only属性。您需要设置backing字段,但不能通过属性来完成,因为据说此属性是只读属性或不带setter方法的属性。此类属性的目的是对您的对象做出合同声明"此属性无法设置">

这类似于拥有私有setter,但是,不能在接口定义中强制使用访问修饰符。因此,在定义数据契约和对象接口时,这种语法有一个特定的目的,也就是说"不能通过契约设置此属性,并且任何子类都不能将公共setter作为此契约的一部分公开。">

顺便说一句,您可以使用反射绕过访问修饰符,但这种情况并不常见(99%的.NET开发人员可能不知道这一事实。(

通常,通过构造函数、反射或作为对象初始化的一部分来设置支持字段。

这也是核心句法,它构成了现代句法糖的基础。考虑以下属性定义:

    public int MyProperty { get; set; }

这完全是语法上的糖,实际上对C#1.0编译器无效。今天,在编译时,将代表您生成一个支持字段。因此,以下语法仅对接口定义有效(否则它永远不会返回有意义的值(

    public int MyProperty { get; }

以上是使用较新的自动属性语法创建只读属性的尝试(无效(。

参考文献:

  1. 何时应使用Readonly和Get-only属性
  2. 为getter和setter使用backing变量
  3. 是否可以访问自动实现属性后面的支持字段
  4. https://msdn.microsoft.com/en-us/library/bb384054.aspx
  5. https://msdn.microsoft.com/en-us/library/w86s7x04.aspx