我如何使用财产{get; }?

时间:2015-05-27 22:46:27

标签: c# visual-studio-2013 xna

我注意到在Microsoft.Xna.Framework.Rectangle struct中,有很多属性只是public int Bottom { get; }public Point Center { get; }。对于我的生活,我无法弄清楚这里发生了什么。我已经尝试在我自己的一些结构中复制它,但我无法弄清楚如何在没有set;关键字的情况下给它一个值。 Rectangle struct{get;}做了什么?

3 个答案:

答案 0 :(得分:1)

这意味着以后无法设置属性为您提供访问权限的基础值..您只能"得到"潜在价值。

当您实例化Rectangle时,您必须传递一些值:

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

我的猜测(不看源代码)是属性值(CenterBottom等)都在构造函数中设置。您以后无法更改它们。要么寻找另一个要设置的属性(即XY),要么根据现有属性创建新的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位置?改变高度?不可能知道。因此,您必须自行决定并根据您的实际需要更改TopHeight

属性的概念不仅仅是拥有变量并设置或获取它。如果它是我们可以使用公共变量,那就是它。相反,我们的想法是允许验证和计算属性。

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 propertya 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 fieldgenerated on your behalf。因此,以下语法仅对接口定义有效(否则它将永远不会返回有意义的值。)

    public int MyProperty { get; }

以上是使用较新的read-only property语法创建auto-property的(无效)尝试。

参考文献:

  1. When should use Readonly and Get only properties
  2. Using a backing variable for getters and setters
  3. Is it possible to access backing fields behind auto-implemented properties?
  4. https://msdn.microsoft.com/en-us/library/bb384054.aspx
  5. https://msdn.microsoft.com/en-us/library/w86s7x04.aspx