Thursday, February 1, 2007

C# ReadOnly class

This class is meant for variables in C# that must be readonly.
Offcourse you can use the "readonly" keyword of C#, but you can only initialize it in the constructor of a type.

This little class makes it possible to initialize it in the constructor and assign it once somewhere else. The class is generic and supports implicit casting to the generic type.

usage:


   1: int x = 0; 
   2: ReadOnly myInt = new ReadOnly(); 
   3: myInt = 10; 
   4: x = myInt; 
   5: myInt = 15; // throws an exception 
   6: Console.WriteLine("val: {0}", x); 


The class definition:


   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4:  
   5: namespace Whizzo
   6: {
   7:     public struct ReadOnly
   8:     {
   9:         private static ReadOnlyVar? _readOnlyVar;
  10:  
  11:         #region Constructor
  12:  
  13:         public ReadOnly(T var)
  14:         {
  15:             _readOnlyVar = new ReadOnlyVar(var);
  16:         }
  17:  
  18:         #endregion
  19:  
  20:         #region Implicit casts
  21:  
  22:         /// 
  23:         /// User-defined conversion from T to ReadOnly
  24:         /// 
  25:         /// type to cast to
  26:         /// a new readonly variable, filled in
  27:         public static implicit operator ReadOnly(T var)
  28:         {
  29:             if (_readOnlyVar == null)
  30:                 return new ReadOnly(var);
  31:             throw new InvalidOperationException("Variable is read-only, and already assigned.");
  32:         }
  33:  
  34:         /// 
  35:         /// User-defined conversion from ReadOnly to T
  36:         /// 
  37:         /// 
  38:         /// 
  39:         public static implicit operator T(ReadOnly var)
  40:         {
  41:             return _readOnlyVar.HasValue ? _readOnlyVar.Value.Var : default(T);
  42:         }
  43:  
  44:         #endregion
  45:  
  46:         #region Overrides
  47:  
  48:         public override string ToString()
  49:         {
  50:             return _readOnlyVar.HasValue ? _readOnlyVar.Value.Var.ToString() : "No value";
  51:         }
  52:  
  53:         #endregion
  54:  
  55:         #region Nested Types
  56:  
  57:         private struct ReadOnlyVar
  58:         {
  59:             private readonly T _var;
  60:  
  61:             public ReadOnlyVar(T var)
  62:             {
  63:                 _var = var;
  64:             }
  65:  
  66:             public T Var
  67:             {
  68:                 get { return _var; }
  69:             }
  70:         }
  71:  
  72:         #endregion
  73:     }
  74: }


Just copy the code into a ReadOnly.cs file or something like that, and start using ;)
There are many different ways to make something like this, but i find this a handy way.

No comments: