Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a "mostly complete" (im)mutability approach for C#? [closed]

Since immutability is not fully baked into C# to the degree it is for F#, or fully into the framework (BCL) despite some support in the CLR, what's a fairly complete solution for (im)mutability for C#?

My order of preference is a solution consisting of general patterns/principles compatible with

  • a single open-source library with few dependencies
  • a small number of complementary/compatible open-source libraries
  • something commercial

that

  • covers Lippert's kinds of immutability
  • offers decent performance (that's vague I know)
  • supports serialization
  • supports cloning/copying (deep/shallow/partial?)
  • feels natural in scenarios such as DDD, builder patterns, configuration, and threading
  • provides immutable collections

I'd also like to include patterns you as the community might come up with that don't exactly fit in a framework such as expressing mutability intent through interfaces (where both clients that shouldn't change something and may want to change something can only do so through interfaces, and not the backing class (yes, I know this isn't true immutability, but sufficient):

public interface IX {     int Y{ get; }     ReadOnlyCollection<string> Z { get; }     IMutableX Clone(); }  public interface IMutableX: IX {     new int Y{ get; set; }     new ICollection<string> Z{ get; } // or IList<string> }  // generally no one should get ahold of an X directly internal class X: IMutableX {     public int Y{ get; set; }      ICollection<string> IMutableX.Z { get { return z; } }      public ReadOnlyCollection<string> Z     {         get { return new ReadOnlyCollection<string>(z); }     }      public IMutableX Clone()     {         var c = MemberwiseClone();         c.z = new List<string>(z);         return c;     }      private IList<string> z = new List<string>();        }  // ...  public void ContriveExample(IX x) {     if (x.Y != 3 || x.Z.Count < 10) return;     var c= x.Clone();     c.Y++;     c.Z.Clear();     c.Z.Add("Bye, off to another thread");     // ... } 
like image 910
Kit Avatar asked Oct 05 '11 14:10

Kit


1 Answers

Would the better solution be to just use F# where you want true immutability?

like image 64
Chris Marisic Avatar answered Oct 12 '22 20:10

Chris Marisic