Why are C# structs immutable?
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:
- Why are C# structs immutable? 5 answers
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?的更多相关文章
- [易学易懂系列|rustlang语言|零基础|快速入门|(11)|Structs结构体]
[易学易懂系列|rustlang语言|零基础|快速入门|(11)] 有意思的基础知识 Structs 我们今天来看看数据结构:structs. 简单来说,structs,就是用来封装相关数据的一种数据 ...
- Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 对不可靠的客户代 ...
- [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 ...
- [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- 扼杀 304,Cache-Control: immutable
随着近些年社交网站的流行,越来越多的人学会了“刷”网页 ── 刷微博,刷朋友圈,刷新闻,刷秒杀页.这里的“刷”,就是刷新的意思,在浏览器里,你可以通过点击刷新按钮,或者用快捷键,或者移动端的下拉操作来 ...
- Structs框架
一.准备工作及实例 1.解压struts-2.1.6-all.zip(structs网上下载) apps目录:struts2自带的例子程序 docs目录:官方文档. lib 目录:存放所有jar文件. ...
- Immutable api example
var temp=[{name:"kitty",age:31},{name:"ff",age:22},{name:"kitty",age:4 ...
- Immutable笔记
Immutable笔记 转换成js数据 获取或则改变嵌套式imutable数据类型
- 第一个structs+spring+hibernate的web程序
1. 数据库: Column Type Comment id int(11) Auto Increment name varchar(50) NULL url varchar(255) NUL ...
随机推荐
- 【Git的基本操作十】远程库分支操作
远程库分支操作 1. 推送分支 在本地库新建分支 git branch [新分支名] 如创建一个develop分支: git branch develop 推送分支(将新分支发布在github上) g ...
- vue中的常用三元
点击事件的三元 <el-button type="primary" @click="edit == 'mod' ? sureModify() : submit()& ...
- SmartBinding与kbmMW#3
前言 在SmartBinding #2中,我介绍了新的自动绑定功能,支持在Form设计器中直接定义绑定.不仅如此,kbmMW SmartBind还有更多很酷的功能,即将发布的kbmMW中的SmartB ...
- Java学习笔记【四、类、对象、接口】
编程语言的发展 机器语言 过程语言 面向对象编程--封装.继承.多态 关键字 extends implements override overload super this static abstra ...
- GPS坐标转大地坐标
根据网上EXCEL表格给出的关系,生成的C语言代码.计算结果和软件[万能坐标转换980]计算出的结果很接近. double B = 39.3926; double L = 117.4514; //do ...
- shell脚本基础和grep文本处理工具企业应用2
shell脚本编程: 编程语言的分类: 根据运行方式 编译运行:源代码-->编译器(编译)-->程序文件 优 ...
- C++第四次作业--继承与派生
C++ 继承 面向对象程序设计中最重要的一个概念是继承.继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易.这样做,也达到了重用代码功能和提高执行效率的效果. 当创建一个类时 ...
- 嵌入式Linux下CAN总线配置
问题背景:本人开发板使用的是迅为iTOP4412精英版,额外购买的CAN/485模块,如下图: 但是插上模块之后,在终端使用ifconfig can0命令发现开发板读不到CAN设备,显示“ifconf ...
- hive的事物性 transaction manager
create table lk3 (id string,nname string,grade int,goldUser int); insert into lk3 values (,, ), (,, ...
- poj 3641 Pseudoprime numbers 快速幂+素数判定 模板题
Pseudoprime numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7954 Accepted: 3305 D ...
