我使用的是自动实现的属性。 我想解决以下是声明我自己的后盾变量的最快方法?
public Point Origin { get; set; }
Origin.X = 10; // fails with CS1612
错误消息:因为它不是一个可变无法修改“表达”的返回值
已尝试修改,这是一个中间表达式的结果值类型。 因为该值不持久,则该值将保持不变。
要解决此误差,则表达式的结果存储在一个中间值,或使用引用类型为中间表现。
我使用的是自动实现的属性。 我想解决以下是声明我自己的后盾变量的最快方法?
public Point Origin { get; set; }
Origin.X = 10; // fails with CS1612
错误消息:因为它不是一个可变无法修改“表达”的返回值
已尝试修改,这是一个中间表达式的结果值类型。 因为该值不持久,则该值将保持不变。
要解决此误差,则表达式的结果存储在一个中间值,或使用引用类型为中间表现。
这是因为Point
是一个值类型( struct
)。
正因为如此,当您访问的Origin
你所访问由类持有的值的副本属性,而不是本身的价值,你会与一个引用类型( class
),因此,如果您设置的X
属性上,那么你“重新设定副本上属性,然后将其丢弃,离开原来的值不变。 这可能不是你打算什么,这就是为什么编译器警告你一下吧。
如果你想改变只是X
值,你需要做的是这样的:
Origin = new Point(10, Origin.Y);
使用支持变量也无济于事。 该Point
类型是值类型。
您需要分配整点价值的原产地属性: -
Origin = new Point(10, Origin.Y);
问题是,当你访问源属性是什么返回get
是点结构的起源属性自动创建领域的副本。 因此,你的X字段修改这个副本不会影响底层的领域。 编译器检测到这一点,并给你一个错误,因为这种操作是完全无用的。
即使你用你自己的后盾变量的get
看起来像: -
get { return myOrigin; }
你还是会返回Point结构的副本,你会得到同样的错误。
嗯...有更多的仔细阅读你的问题也许你实际上意味着直接从您的类中修改后盾变量: -
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;
这看起来像一个非常奇怪的事情, 不是建议。 刚刚上市的另一种方法。 更好的方法做的是使结构不变,并提供适当的构造函数。
问题是,你点到位于堆栈上的值和值不会relfected回一部开拓创新属性,因此C#不允许你一个参考返回值类型。 我想你可以通过删除产地属性解决这个,而是使用公共提交的,是的,我知道这不是一个很好的解决方案。 另一种解决方案是不使用的点,而是创建自己的点类型为对象。
我想这里的缺点是,你正试图在分配Statement对象的子值,而不是分配对象本身。 您需要分配整个Point对象在这种情况下,物业类型为点。
Point newOrigin = new Point(10, 10);
Origin = newOrigin;
希望我做的意义有
除了辩论结构与阶级的利弊,我倾向于看目标,并从该角度来处理这个问题。
话虽这么说,如果你不需要写入属性get和set方法背后的代码(如你的例子),那么岂不是很容易直接申报Origin
为类,而不是属性的字段? 我认为,这将让你实现你的目标。
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
class MyClass
{
public Point Origin;
}
MyClass c = new MyClass();
c.Origin.X = 23; // No error. Sets X just fine