Compiler Error CS1612 Cannot modify the return value of 'expression' because it is not a variable

 class Transform
{
public Point p { get; set; } public Point p2;
public void ShowV()
{
Console.WriteLine(p.X + "..." + p.Y);
}
} [Test]
public void TestChuck()
{
Transform t = new Transform();
t.p.X = ;
t.p2.X = ;
t.ShowV();
Console.Read();
}

t.p = new Point();  这个可以,set可以工作。 但是get出来的是value

Why are C# structs immutable?

问题

I was just curious to know why structs, strings etc are immutable? What is the reason for making them immutable and rest of the objects as mutable. What are the things that are considered to make an object immutable?

Is there any difference on the way how memory is allocated and deallocated for mutable and immutable objects?

 解答:

If this subject interests you, I have a number of articles about immutable programming at http://blogs.msdn.com/b/ericlippert/archive/tags/immutability/

I was just curious to know why structs, strings etc are immutable?

Structs and classes are not immutable by default, though it is a best practice to make structs immutable. I like immutable classes too.

Strings are immutable.

What is the reason for making them immutable and rest of the objects as mutable.

Reasons to make all types immutable:

  • It is easier to reason about objects that do not change. If I have a queue with three items in it, I know it is not empty now, it was not empty five minutes ago, it will not be empty in the future. It's immutable! Once I know a fact about it, I can use that fact forever. Facts about immutable objects do not go stale.

  • A special case of the first point: immutable objects are much easier to make threadsafe. Most thread safety problems are due to writes on one thread and reads on another; immutable objects don't have writes.

  • Immutable objects can be taken apart and re-used. For example, if you have an immutable binary tree then you can use its left and right subtrees as subtrees of a different tree without worrying about it. In a mutable structure you typically end up making copies of data to re-use it because you don't want changes to one logical object affecting another. This can save lots of time and memory.

Reasons to make structs immutable

There are lots of reasons to make structs immutable. Here's just one.

Structs are copied by value, not by reference. It is easy to accidentally treat a struct as being copied by reference. For example:

void M()
{
S s = whatever;
... lots of code ...
s.Mutate();
... lots more code ...
Console.WriteLine(s.Foo);
...
}

Now you want to refactor some of that code into a helper method:

void Helper(S s)
{
... lots of code ...
s.Mutate();
... lots more code ...
}

WRONG! That should be (ref S s) -- if you don't do that then the mutation will happen on a copy of s. If you don't allow mutations in the first place then all these sorts of problems go away.

Reasons to make strings immutable

Remember my first point about facts about immutable structures staying facts?

Suppose string were mutable:

public static File OpenFile(string filename)
{
if (!HasPermission(filename)) throw new SecurityException();
return InternalOpenFile(filename);
}

What if the hostile caller mutates filename after the security check and before the file is opened? The code just opened a file that they might not have permission to!

Again, mutable data is hard to reason about. You want the fact "this caller is authorized to see the file described by this string" to be true forever, not until a mutation happens. With mutable strings, to write secure code we'd constantly have to be making copies of data that we know do not change.

What are the things that are considered to make an object immutable?

Does the type logically represent something that is an "eternal" value? The number 12 is the number 12; it doesn't change. Integers should be immutable. The point (10, 30) is the point (10, 30); it doesn't change. Points should be immutable. The string "abc" is the string "abc"; it doesn't change. Strings should be immutable. The list (10, 20, 30) doesn't change. And so on.

Sometimes the type represents things that do change. Mary Smith's last name is Smith, but tomorrow she might be Mary Jones. Or Miss Smith today might be Doctor Smith tomorrow. The alien has fifty health points now but has ten after being hit by the laser beam. Some things are best represented as mutations.

Is there any difference on the way how memory is allocated and deallocated for mutable and immutable objects?

Not as such. As I mentioned before though, one of the nice things about immutable values is that something you can re-use parts of them without making copies. So in that sense, memory allocation can be very different.

Change the value of a property of a struct in C# [duplicate]

问题:

This question already has an answer here:

I was reading a book and found out that structs are actually immutable objects. But they have getters and setters. I was wondering if a property of structs can be changed after it has been created.

public struct Test
{
public string str {get; set; }
public int int1 {get; set; }
}

Can the values of 'str' and 'int1' be changed once they have been assigned a value?

解答:

structs are not automatically immutable, but because of certain issues it is strongly recommended to make them immutable yourself. You may be thinking of a similar problem where you can't change the properties of a struct if the struct is itself being accessed as a property (one of the reasons why it is recommended to make them immutable.) Using your Test example:

public struct Test {
public string str { get; set; }
public int int1 { get; set; }
} // This works:
Test value = new Test();
value.str = "asdf";
value.int1 = 5; // But this does NOT work.
Test TestProperty { get; set; } TestProperty.str = "asdf";
TestProperty.int1 = 5;

The reason the second part doesn't work is that you are only getting a value copy by saying TestProperty, and then you set the value of the copy's properties, rather than the one in your object.

To make your struct immutable you would do something like this:

public struct Test {
readonly string mStr;
readonly int mInt1; public string str { get { return mStr; } }
public int int1 { get { return mInt1; } } public Test(string pStr, int pInt1) {
mStr = pStr;
mInt1 = pInt1;
}
}

You can create instances of Test, you can read their properties, but you can't change their properties, except by making a new instance.

Accessing and changing structs as property vs as field

问题

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.

Take a look at this code:

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.

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

With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.

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.

Section "11.3.3" of the specifcation:

When a property or indexer of a struct is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. If the instance expression is classified as a value, a compile-time error occurs. This is described in further detail in §7.17.1.

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

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

Given the declarations:

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; }
}
}

in the example

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

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;

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

Why are C# structs immutable?的更多相关文章

  1. [易学易懂系列|rustlang语言|零基础|快速入门|(11)|Structs结构体]

    [易学易懂系列|rustlang语言|零基础|快速入门|(11)] 有意思的基础知识 Structs 我们今天来看看数据结构:structs. 简单来说,structs,就是用来封装相关数据的一种数据 ...

  2. Immutable(不可变)集合

    不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 对不可靠的客户代 ...

  3. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  4. [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  5. 扼杀 304,Cache-Control: immutable

    随着近些年社交网站的流行,越来越多的人学会了“刷”网页 ── 刷微博,刷朋友圈,刷新闻,刷秒杀页.这里的“刷”,就是刷新的意思,在浏览器里,你可以通过点击刷新按钮,或者用快捷键,或者移动端的下拉操作来 ...

  6. Structs框架

    一.准备工作及实例 1.解压struts-2.1.6-all.zip(structs网上下载) apps目录:struts2自带的例子程序 docs目录:官方文档. lib 目录:存放所有jar文件. ...

  7. Immutable api example

    var temp=[{name:"kitty",age:31},{name:"ff",age:22},{name:"kitty",age:4 ...

  8. Immutable笔记

    Immutable笔记 转换成js数据 获取或则改变嵌套式imutable数据类型  

  9. 第一个structs+spring+hibernate的web程序

    1. 数据库: Column Type Comment id int(11) Auto Increment   name varchar(50) NULL   url varchar(255) NUL ...

随机推荐

  1. React学习——通过模态框中的表单,学习父子组件之间传值

    import { Button, Modal, Form, Input, Radio } from 'antd'; const CollectionCreateForm = Form.create({ ...

  2. Sublime Text 3:自定义语法高亮

    (http://ilkinulas.github.io/programming/2016/02/05/sublime-text-syntax-highlighting.html) 要安装"P ...

  3. NativeScript —— 初级入门(跨平台的手机APP应用)《一》

    NativeScript简介 NativeScript是一个相当新的开源开发系统,几乎完全用JavaScript创建跨平台移动应用程序,带有一些可选的CSS和XML来简化显示布局的开发.您可以在htt ...

  4. 语义分割之RefineNet

    背景介绍 近来年,深度卷积网络在目标检测方面取得了一定的成绩.但对于密集预测,仍存在一定不足,原因是频繁的卷积和池化导致最终的特征分辨率降低. 针对这个问题,目前主要采用两种方法:第一种:空洞卷积,如 ...

  5. ad 拼板

    随着整个电子产业的不断发展,电子行业的很多产品都已经有完善的上下游配套企业.从一个成熟产品的方案设计,外观设计,加工制造,装配测试,包装,批发商渠道等等,这样的一条产业链在特定的环境就这样自然地生成. ...

  6. Maximum Xor Secondary CodeForces - 281D (单调栈)

    Bike loves looking for the second maximum element in the sequence. The second maximum element in the ...

  7. MFC总结

    1.首先是ListControl 简介: 列表视图控件List Control同样比较常见,它能够把任何字符串内容以列表的方式显示出来,这种显示方式的特点是整洁.直观,在实际应用中能为用户带来方便. ...

  8. 【杂题】cf1041fF. Ray in the tube

    死于没有处理边界 题目描述 题目大意 在两面镜子上各选定一个整数位置的点 A 与 B,并从其中一个点向另一个射出一条光线,使得接收到光线的传感器数量尽可能的多.传感器不重叠. 题目分析 我们来初步考虑 ...

  9. 基于Kibana的可视化监控报警插件sentinl入门

    sentinl是什么 Kibi/Kibana Alert & Reporting App Watching your data, 24/7/365 sentinl是一个免费的kibana预警与 ...

  10. 原生 JS实现一个简单分页插件

    最近做的一个 PC端的需求,这个需求中有一个小点,页面底部有一块列表区域,这个列表的数据量比较大,需要进行分页控制,切换页码的时候,发送一个 ajax请求,在页面无刷新的情况下,实现列表数据的刷新,所 ...