访问和更改结构作为属性与作为字段

访问和更改结构作为属性与作为字段

本文介绍了访问和更改结构作为属性与作为字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我会开始我的问题,说我了解可变结构背后的邪恶,但我正在使用 SFML.net 并使用大量 Vector2f 和此类结构.

Ok, I'll start my question saying that I understand the evil behind mutable structs, but I'm working with SFML.net and using a lot of Vector2f and such structs.

我不明白的是为什么我可以拥有并更改类中的字段的值,而不能对同一个类中的属性执行相同操作.

What I don't get it is why I can have, and change the values of, a field in a class and can't do the same with a property, in the very same class.

看看这段代码:

using System;

namespace Test
{
    public struct TestStruct
    {
        public string Value;
    }

    class Program
    {
        TestStruct structA;
        TestStruct structB { get; set; }

        static void Main(string[] args)
        {
            Program program = new Program();

            // This Works
            program.structA.Value = "Test A";

            // This fails with the following error:
            // Cannot modify the return value of 'Test.Program.structB'
            // because it is not a variable
            //program.structB.Value = "Test B";

            TestStruct copy = program.structB;
            copy.Value = "Test B";

            Console.WriteLine(program.structA.Value); // "Test A"
            Console.WriteLine(program.structB.Value); // Empty, as expected
        }
    }
}

注意:我将构建自己的类来覆盖相同的功能并保持我的可变性,但我看不出为什么我可以做一个而不能做其他的技术原因.

note: I'll build my own classes to cover the same functionality and keep with my mutability, but I can't see a technical reason why I can do one and can't do other.

推荐答案

当您访问一个字段时,您正在访问实际的结构.当您通过属性访问它时,您调用了一个方法,该方法返回存储在属性中的任何内容.在结构体是值类型的情况下,您将获得该结构体的副本.显然,该副本不是变量,无法更改.

When you access a field, you are accessing the actual struct. When you access it through property, you call a method that returns whatever is stored in the property. In the case of a struct, which is a value type, you will get back a copy of the struct. Apparently that copy is not a variable and cannot be changed.

C# 语言规范 5.0 的1.7 结构"部分说:

Section "1.7 Structs" of the C# language specification 5.0 says:

对于类,两个变量可以引用相同的对象,因此对一个变量的操作可能会影响另一个变量引用的对象.对于结构,变量每个人都有自己的数据副本,这是不可能的一个操作会影响另一个.

这说明您将收到结构的副本,并且无法修改原始结构.但是,它没有说明为什么不允许这样做.

That explains that you will receive a copy of the struct and not be able to modify the original struct. However, it doesn't describe why it isn't allowed.

规范的11.3.3"部分:

Section "11.3.3" of the specifcation:

当结构的属性或索引器是赋值的目标时,与属性或索引器访问相关联的实例表达式必须归类为变量.如果实例表达式是归类为值,则会发生编译时错误.这是描述在 §7.17.1 中进一步详细说明.

所以从 get 访问器返回的东西"是一个值而不是一个变量.这解释了错误消息中的措辞.

So the returned "thing" from the get accessor is a value and not a variable. That explains the wording in the error message.

规范在第 7.17.1 节中还包含一个与您的代码几乎相同的示例:

The specification also contains an example in section 7.17.1 that is nearly identical to your code:

鉴于声明:

struct Point
{
    int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int X {
        get { return x; }
        set { x = value; }
    }
    public int Y {
        get { return y; }
        set { y = value; }
    }
}
struct Rectangle
{
    Point a, b;
    public Rectangle(Point a, Point b) {
        this.a = a;
        this.b = b;
    }
    public Point A {
        get { return a; }
        set { a = value; }
    }
    public Point B {
        get { return b; }
        set { b = value; }
    }
}

示例中

Point p = new Point();
p.X = 100;
p.Y = 100;
Rectangle r = new Rectangle();
r.A = new Point(10, 10);
r.B = p;

对 p.X、p.Y、r.A 和 r.B 的赋值是允许的,因为 p 和 r 是变量.但是,在示例中

the assignments to p.X, p.Y, r.A, and r.B are permitted because p and r are variables. However, in the example

Rectangle r = new Rectangle();
r.A.X = 10;
r.A.Y = 10;
r.B.X = 100;
r.B.Y = 100;

赋值都是无效的,因为 r.A 和 r.B 不是变量.

the assignments are all invalid, since r.A and r.B are not variables.

这篇关于访问和更改结构作为属性与作为字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 06:24