无法修改返回值错误c#
我正在使用自动实现的属性。 我想最快的方法来解决以下是宣布我自己的支持variables?
public Point Origin { get; set; } Origin.X = 10; // fails with CS1612
错误消息:无法修改“expression式”的返回值,因为它不是一个variables
试图修改作为中间expression式的结果的值types。 由于该值不是持久的,因此该值将保持不变。
要解决此错误,请将expression式的结果存储在中间值中,或者使用中间expression式的引用types。
这是因为Point
是一个值types( struct
)。
正因为如此,当你访问Origin
属性时,你正在访问这个类所拥有的值的一个副本 ,而不是像引用types( class
)那样的值本身,所以如果你设置了它的X
属性,那么你在副本上设置属性,然后丢弃它,保持原始值不变。 这可能不是你想要的,这就是为什么编译器会警告你。
如果你想改变X
值,你需要做这样的事情:
Origin = new Point(10, Origin.Y);
使用支持variables将无济于事。 Point
types是一个Valuetypes。
您需要将整个Point值分配给Origin属性: –
Origin = new Point(10, Origin.Y);
问题是当你访问Origin属性时, get
返回的是Origin属性自动创build字段中Point结构的副本。 因此,您修改X字段的副本不会影响基础字段。 编译器检测到这一点,并给你一个错误,因为这个操作是完全无用的。
即使你使用自己的支持variables,你get
像: –
get { return myOrigin; }
你仍然会返回一个Point结构的副本,你会得到同样的错误。
嗯…更仔细地阅读你的问题,或许你实际上是直接修改你的课堂上的支持variables:
myOrigin.X = 10;
是的,那将是你需要的。
现在你已经知道错误的来源是什么了。 如果一个构造函数不存在一个带你的属性的重载(在这个例子中是X
),你可以使用对象初始值设定项(它将在后台执行所有的魔术)。 不是说你不需要让你的结构不可改变 ,而只是给出额外的信息:
struct Point { public int X { get; set; } public int Y { get; set; } } class MyClass { public Point Origin { get; set; } } MyClass c = new MyClass(); c.Origin.X = 23; //fails. //but you could do: c.Origin = new Point { X = 23, Y = c.Origin.Y }; //though you are invoking default constructor //instead of c.Origin = new Point(23, c.Origin.Y); //in case there is no constructor like this.
这是可能的,因为幕后发生:
Point tmp = new Point(); tmp.X = 23; tmp.Y = Origin.Y; c.Origin = tmp;
这看起来像一个非常奇怪的事情,根本不build议。 只是列出一个替代方法。 更好的方法是使结构不可变,并提供一个适当的构造函数。
问题是你指向一个位于栈上的值,这个值不会被重新映射到orignal属性,所以C#不允许你返回一个值types的引用。 我认为你可以通过删除Origin属性来解决这个问题,而是使用一个公共提交,是的,我知道这不是一个好的解决scheme。 另一种解决scheme是不使用Point,而是创build自己的Pointtypes作为对象。
我想这里的catch是你正在试图在语句中分配对象的子值而不是分配对象本身。 在这种情况下,您需要指定整个Point对象,因为属性types是Point。
Point newOrigin = new Point(10, 10); Origin = newOrigin;
希望我在那里有道理