Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Friday, July 6, 2012

c# readonly vs constant in different assembly

In C#/.NET we can declare a constant value by either using keyword 'const' or 'readonly' . Using const keyword will define compile time constant and readonly will define runtime. Only the C# built-in types can be declared using 'const' for user-defined types like class, struct or array use 'readonly'. Compiler will have a literal value for all the fields that declared const, so if you decompile the code you will find no reference to the constant but actual value. Compile time constant are faster then readonly but are less flexible and can create issues if not used properly. As a general rule one should strictly use compile time constant only for values that are never going to change for example defining value of PI, any value that might change in future use readonly.

During developing a large application there are numerous scenario where you might have to choose between compile-time and run-time constant's. Compile time constants are faster then run-time, although in certain conditions to avoid potential problems you might want to consider using run-time constants . The difference between the two is more clearly explained in this post [ linky ]

Here is an practical example, two teams are working on a same project one team develops a external class library and other team develops the main application. Team one has developed the class library that has some const and readonly variables, these values are consumed in the application developed by the team two. If in future team one updates the constant value in the external class library and the application is not recompiled it would not reflect the new value. This issue is only created if your are using constant values form external assemblies. If a const value changes in a assembly then you need to rebuild all the clients applications dependent on it.




   1:  using System;
   2:  using ExternalLibrary;
   3:   
   4:  namespace ExternalLibrary
   5:  {
   6:      public class ConstantLib
   7:      {
   8:          public static readonly int StartValue = 105;
   9:          public const int EndValue = 120;
  10:          public readonly int ReadonlyValue = 555;
  11:      }
  12:  }
  13:   
  14:   
  15:   
  16:  namespace CTvsRT
  17:  {
  18:     class Program
  19:     {
  20:        static void Main(string[] args)
  21:        {
  22:         ConstantLib cl = new ConstantLib();
  23:   
  24:         Console.WriteLine("ConstantLib.StartValue {0}", ConstantLib.StartValue.ToString());
  25:         Console.WriteLine("ConstantLib.EndValue {0}", ConstantLib.EndValue.ToString());
  26:         Console.WriteLine("ConstantLib.readonlyValue {0}", cl.ReadonlyValue.ToString());
  27:   
  28:         Console.Read();
  29:        }
  30:     }
  31:  }

Monday, August 9, 2010

Cloning a generic List<T>

Today we had to do a copy operation on a generic list to accomplish a business logic on our server. The situation was such that we had retrieved some data from the database and then store it in a List<T> which was on our corporate servers. Based on a formula we had to remove some elements from the list , a copy of the original collection should be persisted so in case of any error/exception the original data can be resorted.

You might already knows how to implement IClonable interface but for those who are not aware, I will explain the method to clone the generic list.
To make a copy of generic list we need to perform this steps

1) Derive our data class from IClonable
2) Implement the members of IClonable
3) Write a extension method .on List<T>

IClonable is the way C# implements the copy constructor the basic fundamental is to create a copy of the object . The System.ICloneable interface defines a method of create a new instance of a class with the identical value as an existing instance. There are two ways of cloning

1) Shallow Cloning – all objects are copied but only link of the referred objects are copied
2) Deep Cloning- all the object are copied along with the referred objects

shallow_cloning

The above figure describes a shallow copy of objects looks in memory, we have a class object called DataClassObj1containing two objects which we call as the ContainingObject. In the second part of the figure we have another object DataClassObj2 which is a shallow copy of DataClassObj1. DataClassObj1 and DataClassObj2 are having reference to same object, so changes made through any of the DataClassObj will be reflected in the other on the other hand if it was a deep copy then both the objects would have their individual ContainingObjects and changes made in one would not be reflected in the other.

A shallow copy is by far the easiest way to clone your class, shallow copy in .net can be done by MemberwiseCloning and every object inherited from Object class can use this method to get a shallow clone. Below is the sample code illustrating how to use ICloneable and MeberwiseClone();

  1:    [Serializable]
  2:     public class ContainingObject
  3:     {
  4:         public string sName;                
  5:     }
  6: 
  7:     [Serializable]
  8:     public class DataClass:ICloneable
  9:     {
 10:         
 11:         public ContainingObject ContainingObject1;
 12:         public ContainingObject ContainingObject2;
 13: 
 14:         public DataClass()
 15:         {
 16:             ContainingObject1 = new ContainingObject();
 17:             ContainingObject2 = new ContainingObject();
 18:         }
 19:         public object Clone()
 20:         {
 21:             return MemberwiseClone();
 22:         }
 23:     }

Now the problem with shallow cloning is that if you change a reference object in the clone the original reference is also changed. for example in below line of code when the line 4 is executed both d1.ContainingObject1.sName and d1.ContainingObject1.sName are changed to “Amin”.

  1: DataClass d1 = new DataClass();
  2: d1.ContainingObject1.sName = "Vikas";
  3: DataClass d2 = d1.Clone() as DataClass;
  4: d2.ContainingObject1.sName = "Amin";



For a deep cloning of the object we can use below extension method that will deep copy any object

  1:   using System.IO;
  2:     using System.Runtime.Serialization.Formatters.Binary;
  3:     public static class DeePCloneExtensionMethod
  4:     {
  5:         public static T DeepClone<T>(this T a)
  6:         {
  7:             using (MemoryStream stream = new MemoryStream())
  8:             {
  9:                 BinaryFormatter formatter = new BinaryFormatter();
 10:                 formatter.Serialize(stream, a);
 11:                 stream.Position = 0;
 12:                 return (T)formatter.Deserialize(stream);
 13:             }
 14:         }
 15:     }