不可变对象
  不可变(immutable): 即对象一旦被创建初始化后,它们的值不能被改变,之后的每次改变都会产生一个新对象。
  var str="mushroomsir";
  str.Substring(0, 6)
  c#中的string是不可变的,Substring(0, 6)返回的是一个新字符串值,而原字符串在共享域中是不变的。另外一个StringBuilder是可变的,这也是推荐使用StringBuilder的原因。
  var age=18;
  当存储值18的内存分配给age变量时,它的内存值也是不可以被修改的。
  age=2;
  此时会在栈中开辟新值2赋值给age变量,而不能改变18这个内存里的值,int在c#中也是不可变的。
  class Contact
  {
  public string Name { get;  set; }
  public string Address { get;  set; }
  public Contact(string contactName, string contactAddress)
  {
  Name = contactName;
  Address = contactAddress;
  }
  }
  var mutable = new Contact("二毛", "清华");
  mutable.Name = "大毛";
  mutable.Address = "北大";
  我们实例化MutableContact赋值给mutable,随后我们可以修改MutableContact对象内部字段值,它已经不是初始后的值,可称为可变(mutable)对象。
  可变对象在多线程并发中共享,是存在一些问题的。多线程下A线程赋值到 Name = “大毛” 这一步,其他的线程有可能读取到的数据是:
  mutable.Name == "大毛";
  mutable.Address == "清华";
  很明显这样数据完整性不能保障,也有称数据撕裂。我们把可变对象更改为不可变对象如下:
  public class Contact2
  {
  public string Name { get; private set; }
  public string Address { get; private set; }
  private Contact2(string contactName, string contactAddress)
  {
  Name = contactName;
  Address = contactAddress;
  }
  public static Contact2 CreateContact(string name, string address)
  {
  return new Contact2(name, address);
  }
  }
  使用时只能通过Contact2的构造函数来初始化Name和Address字段。Contact2此时即为不可变对象,因为对象本身是个不可变整体。通过使用不可变对象可以不用担心数据完整性,也能保证数据安全性,不会被其他线程修改。