通过引用检索属性

时间:2012-03-06 13:08:08

标签: c# properties pass-by-reference

我是C#的新手。我来自Java世界。所以我对以下代码感到困惑:

    class A
    {
        private PointF point;

        public A(PointF point)
        {
            this.point = point;
        }

        public PointF Position
        {
            get { return point; }
        }
    }

我想更改position属性的X坐标,所以我执行:

        A a = new A(new PointF(1,2));
        PointF p = a.Position;
        p.X = 100;
        Console.WriteLine(a.Position.X); // <--- I have 1 here!

我想知道为什么输出不是 100 ?据我了解,我已收到有关职位属性的私人领域的参考资料。我是对的吗?

我可以在不添加set-property的情况下更改属性,并使用新的 PointF 对象传播位置吗?

8 个答案:

答案 0 :(得分:6)

没有; PointFstruct,因此它具有复制语义而不是对象;一旦你获得它 - 它是一个单独的和孤立的副本(除非你使用像ref / out这样的东西,这是......更微妙)。在您的示例中,实际上会多次复制该结构。

顺便说一句,这样做的结果是拥有可变结构实际上是一个非常糟糕的主意 - 所以在大多数情况下你应该避免你可以说的场景:

p.X = 100;

因为这会导致更多的混乱而不是它有所帮助。特别是以下内容完全无效:

a.Position.X = 100; // won't even compile

(这里编译发现您正在更改仅在突变期间存在的结构的副本,这意味着您的更改无处,并且几乎肯定是一个错误)

答案 1 :(得分:2)

PointF是一个结构。在.Net Framework结构中 valueTypes 。因此,您的示例将始终打印出来。

你在课堂上使用它并不重要。每次为值类型的变量赋值时,将复制值

答案 2 :(得分:2)

PointF是具有所有后果的值类型。 如果要更改属性中PointF值的唯一“X”属性,则需要将值复制到变量中,更改“X”属性并设置更改的属性值。

var cls = new A();
var point = cls.Point;
point.X = 15;
cls.Point = point;

答案 3 :(得分:2)

在C#中有两种类型的变量 - 值类型和引用类型。分配值类型时,将复制它们 - 对于引用类型,将复制引用

Point是一种值类型(struct),并且在分配时会复制。所以:

PointF p = a.Position;

pa.Position副本,完全独立于此。所以:

p.X = 100;

修改Xp的值,保持a.Position.X不变。

答案 4 :(得分:0)

你需要使用保存的单词out(function)和ref(发送到函数时)通过引用传递参数

答案 5 :(得分:0)

我想知道为什么编译器不会给你一个警告。 这里发生的是你没有返回一个PointF引用,它可能是一个值类型,实际上你返回一个副本。然后修改该副本X属性。当然这不行。

答案 6 :(得分:0)

在您的示例中,pa是两个不同的对象,因此更改前者不会影响后者。

答案 7 :(得分:0)

在C#中,您拥有properties

class A 
{ 
    public PointF Position {get;set;} 

    public A(PointF point) 
    { 
        this.Position = point; 
    } 
} 

A a = new A(new PointF(1,2));    
    a.Position.X = 100  
    Console.WriteLine(a.Position.X);