Posts Tagged 'Generics'

C# How to: Deep copy objects using NetDataContractSerializer

Article purpose

This article will illustrate how to create deep copies of an by making use of the implemented in the form of an extension method with generic type support.

Sample source code

This article is accompanied by a sample source code Visual Studio project which is available for download .

Shallow Copy and Deep Copy

When creating a copy of an in memory, the type of copy can be described as either a shallow copy or a deep copy. The class defines the method, which performs a bit by bit copy of an ’s value type members. In the case of reference type members the method will create a copy of the reference, but not a copy of the being referenced. Creating a copy of an using the method will thus result in copies and the original still referencing the same member in memory when that is a reference type. The method performs a shallow copy when invoked.

A deep copy of an results in copies and the original not referencing the same reference type member in memory.

This article is a follow up article on: . When using being have to be decorated with any number of attributes which aid and . An object’s definition has to at the very least specify the Serializable attribute, if not attempting results in a runtime exception.

The advantage of implementing deep copy operations by making use of a can be argued around not having to specify . Although, as is the case with , only objects that define a can be without specifying any additional attributes.

Example custom data type

The code snippet listed below illustrates several user/custom defined data types. Notice the complete absence of any code attributes, as usually required for successful serialization/deserialization. Also pay attention to the private member variables, being an and user defined reference type defined towards the end of this snippet.

For the sake of convenience I overload the , returning a string representation of an object’s member values.

public class CustomDataType 
{ 
     private CustomEnum enumMember = CustomEnum.EnumVal1; 
     private ExampleReferenceType referenceType = new ExampleReferenceType(); 

public void RefreshReferenceType() { referenceType.Refresh(); }
private int intMember = 0; public int IntMember { get { return intMember; } set { intMember = value; } }
private string stringMember = String.Empty; public string StringMember { get { return stringMember; } set { stringMember = value; } }
private DateTime dateTimeMember = DateTime.MinValue; public DateTime DateTimeMember { get { return dateTimeMember; } set { dateTimeMember = value; } }
public override string ToString() { return "IntMember: " + IntMember + ", DateTimeMember: " + DateTimeMember.ToString() + ", StringMember: " + stringMember + ", EnumMember: " + enumMember.ToString() + ", ReferenceType: " + referenceType.ToString(); }
public void SetEnumValue(CustomEnum enumValue) { enumMember = enumValue; } }
public class ExampleReferenceType { private DateTime createdDate = DateTime.Now;
public void Refresh() { createdDate = DateTime.Now; }
public override string ToString() { return createdDate.ToString("HH:mm:ss.fff"); } }
public enum CustomEnum { EnumVal1 = 2, EnumVal2 = 4, EnumVal3 = 8, EnumVal4 = 16, }

The DeepCopy method – Implementation as an extension method with generic type support

Extension method architecture enables developers to create methods which, from a syntactic and implementation point of view appear to be part of an existing data type. create the perception of being updates or additions, literarily extending a data type as the name implies. do not require access to the source code of the particular types being extended, nor does the implementation thereof require recompilation of the referenced types.

This article illustrates a combined implementation of extending the functionality of . The following code snippet provides the definition.

public static class ExtObject 
{ 
    public static T DeepCopy<T>(this T objectToCopy) 
    {    
        MemoryStream memoryStream = new MemoryStream(); 

NetDataContractSerializer netFormatter = new NetDataContractSerializer();
netFormatter.Serialize(memoryStream, objectToCopy);
memoryStream.Position = 0; T returnValue = (T)netFormatter.Deserialize(memoryStream);
memoryStream.Close(); memoryStream.Dispose();
return returnValue; } }

The DeepCopy method is defined as an by virtue of being a static method of a static class and by specifying the keyword in its parameter definition.

DeepCopy additionally defines the <T> which determines the return value’s type and the type of the parameter objectToCopy.

The method body creates an instance of a object and an object instance of type . When the is invoked the Xml representation of the objectToCopy parameter is written to the specified . In a similar fashion is invoked next, reading the Xml representation from the specified . The returned is cast to the same type as the originally .

Note: :

Serializes and deserializes an instance of a type into XML stream or document using the supplied .NET Framework types.

The NetDataContractSerializer differs from the in one important way: the NetDataContractSerializer includes CLR type information in the serialized XML, whereas the does not. Therefore, the NetDataContractSerializer can be used only if both the serializing and deserializing ends share the same CLR types.

In the scenario illustrated it can be considered safe to use since objects being are only persisted to memory for a few milliseconds and then back to an instance.

The implementation

The DeepCopy method illustrated above appears as a member method to the CustomDataType class created earlier.

static void Main(string[] args) 
{ 
    CustomDataType originalObject = new CustomDataType(); 
    originalObject.DateTimeMember = DateTime.Now; 
    originalObject.IntMember = 42; 
    originalObject.StringMember = "Some random string"; 

CustomDataType deepCopyObject = originalObject.DeepCopy(); deepCopyObject.DateTimeMember = DateTime.MinValue; deepCopyObject.IntMember = 123; deepCopyObject.StringMember = "Something else..."; deepCopyObject.SetEnumValue(CustomEnum.EnumVal3); deepCopyObject.RefreshReferenceType();
Console.WriteLine("originalObject: "); Console.WriteLine(originalObject.ToString()); Console.WriteLine();
Console.WriteLine("deepCopyObject: "); Console.WriteLine(deepCopyObject.ToString()); Console.WriteLine();
Console.WriteLine("Press any key..."); Console.ReadKey(); }

The code snippet listed above is a console application which implements the DeepCopy on objects of type CustomDataType. Modifying the member properties of the second object instance will not result in the first instance properties being modified.

NetDataContractDeepCopy

C# How to: Deep copy objects using Binary Serialization

Article purpose

This will illustrate how to create deep copies of an object by making use of binary serialization implemented in the form of an extension method with generic type support.

Sample source code

This is accompanied by a sample source code Visual Studio project which is available for download .

Shallow Copy and Deep Copy

When creating a copy of an object in memory, the type of copy can be described as either a shallow copy or a deep copy. The Object class defines the MemberwiseClone method, which performs a bit by bit copy of an object’s value type members. In the case of reference type members the MemberwiseClone method will create a copy of the reference, but not a copy of the object being referenced. Creating a copy of an object using the MemberwiseClone method will thus result in copies and the original object still referencing the same member object in memory when that object is a reference type. The MemberwiseClone method performs a shallow copy when invoked.

A deep copy of an object results in copies and the original object not referencing the same reference type member object in memory.

Example custom data type

The sample source code provided with this provides a user defined data type, the CustomDataType class of which the code snippet is listed below.

 [Serializable] 
public class CustomDataType  
{ 
   private int intMember = 0; 
   public int IntMember 
   { 
       get { return  intMember; } 
       set { intMember = value; } 
   } 

private string stringMember = String.Empty; public string StringMember { get { return stringMember; } set { stringMember = value; } }
private DateTime dateTimeMember = DateTime.MinValue; public DateTime DateTimeMember { get { return dateTimeMember; } set { dateTimeMember = value; } }
public override string ToString() { return "IntMember: " + IntMember + ", DateTimeMember: " + DateTimeMember.ToString() + ", StringMember: " + stringMember; } }

Notice that the CustomDataType class definition is marked with the . Objects of which the type definition is not marked with the cannot be serialized. Trying to perform serialization on objects not marked as will result in an exception being thrown.

The DeepCopy method – Implementation as an extension method with generic type support

Extension method architecture enables developers to create methods which, from a syntactic and implementation point of view appear to be part of an existing data type. create the perception of being updates or additions, literarily extending a data type as the name implies. do not require access to the source code of the particular types being extended, nor does the implementation thereof require recompilation of the referenced types.

This illustrates a combined implementation of extending the functionality of generic types. The following code snippet provides the definition.

public staticclassExtObject  
{ 
    public static T DeepCopy<T>(this T objectToCopy) 
    { 
         MemoryStream memoryStream = new MemoryStream(); 
         BinaryFormatter binaryFormatter = new BinaryFormatter(); 
         binaryFormatter.Serialize(memoryStream, objectToCopy); 

memoryStream.Position = 0; T returnValue = (T)binaryFormatter.Deserialize(memoryStream);
memoryStream.Close(); memoryStream.Dispose();
return returnValue; } }

The DeepCopy method is defined as an by virtue of being a static method of a static class and by specifying the keyword in its parameter definition.

DeepCopy additionally defines the generic type <T> which determines the return value’s type and the type of the parameter objectToCopy.

The method body creates an instance of a  object and an object instance of type . When is invoked the representation of the objectToCopy parameter is written to the specified . In a similar fashion is invoked next, reading the representation from the specified . The object returned is cast to the same type as the object originally serialized.

The implementation

The DeepCopy method illustrated above appears as a member method to the CustomDataType class created earlier.

 static void Main(string[] args) 
{ 
   CustomDataType originalObject = new CustomDataType(); 
   originalObject.DateTimeMember = DateTime.Now; 
   originalObject.IntMember = 42; 
   originalObject.StringMember = "Some random string"; 

CustomDataType deepCopyObject = originalObject.DeepCopy(); deepCopyObject.DateTimeMember = DateTime.MinValue; deepCopyObject.IntMember = 123; deepCopyObject.StringMember = "Something else...";
Console.WriteLine("originalObject: " ); Console.WriteLine(originalObject.ToString()); Console.WriteLine();
Console.WriteLine("deepCopyObject: " ); Console.WriteLine(deepCopyObject.ToString()); Console.WriteLine();
Console.WriteLine("Press any key..." ); Console.ReadKey(); }

The code snippet listed above is a console application which implements the DeepCopy extension method on objects of type CustomDataType. Modifying the member properties of the second object instance will not result in the first object instance properties being modified.

Deep copy objects using Binary Serialization

C# How to: Implementing Generic Xml Deserialization by extending the string class

Article purpose

The purpose of this article is to illustrate Deserializing Xml data to object data that resides in application memory. Additionally this article details implementing generics, resulting in a single method being able to deserialize multiple object types.

This article relates to the article “C# How to: Implementing Xml Serialization through a generic extension method

Sample source code

This article is accompanied by a sample source code Visual Studio project which is available for download here.

Example custom data type

The sample source code provided with this article provides a user defined data type, the CustomDataType class of which the code snippet is listed below.

 public class  CustomDataType
 {
     private  int intMember = 0;
     public  int IntMember
     {
         get  { return intMember; }
         set  { intMember = value ; }
     }
 
     private  string  stringMember = String.Empty;
     public  string  StringMember
     {
         get { return stringMember; }
         set { stringMember = value ; }
     }
 
     private  DateTime dateTimeMember = DateTime.MinValue;
     public  DateTime  DateTimeMember
     {
         get { return  dateTimeMember; }
         set { dateTimeMember = value ; }
     }
 }

Also included is sample Xml markup which will be used in deserialization. The included Xml was generated by the serialization code sample “C# How to: Implementing Xml Serialization through a generic extension method

 <?xml version= "1.0" encoding="utf-16"?>
 <CustomDataType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd= "http://www.w3.org/2001/XMLSchema">
   <IntMember>42</IntMember>
   <StringMember>Some random string</StringMember>
   <DateTimeMember>2013-02-09T19:20:24.4654399+02:00</DateTimeMember>
 </CustomDataType>

The deserialization method – Implemented as a String type extension method with generic type support

Extension method architecture enables developers to create methods which, from a syntactic and implementation point of view appear to be part of an existing data type. Extension methods create the perception of being updates or additions, literarily extending a data type as the name implies. Extension methods do not require access to the source code of the particular types being extended, nor does the implementation thereof require recompilation of the referenced types.

This article illustrates a combined implementation of extending the string type whilst specifying the generic type to deserialize to. The following code snippet provides the extension method definition.

 public static class ExtString 
 {
     public static T DeserializeXML<T>(this string xmlString)
     {
         T returnValue = default (T);
 
         XmlSerializer serial = new XmlSerializer(typeof (T));
         StringReader reader = new StringReader(xmlString);
         object result = serial.Deserialize(reader);
 
         if (result != null && result is T)
         {
             returnValue = ((T)result);
         }
 
         reader.Close();
 
         return returnValue;
     }
 }

The DeserializeXML method satisfies the requirements of the extension method architecture by being defined as a static method, implemented as a member method of a statically defined class. In addition the method signature features the this keyword preceding all other method parameters. The seemingly contradicting statement of specifying the this keyword in a static context usually serves as a quick indication that a method is implemented as an extension method. Remember that the this keyword provides a reference to the current instance, whereas in the case of static methods and classes there is no current instance, being static results in limiting a type to only one instance accessed as a shared reference.

The DeserializeXML method specifies as a parameter xmlString of type string. When defining an extension method the first parameter specified indicates the type being extended. This method’s definition therefore indicates that the extension method extends the string type.

DeserializeXML’s method definition implements a generic type <T>. The calling code will specify the required type substitute for <T>, which in turn will determine the method’s return type.

The implementation

The DeserializeXML method discussed above will appear as a non-static member method to all objects of type string.

 static  void  Main(string [] args)
 {
     if  (File.Exists("CustomDataType.xml") == true)
     {
         string  xmlString = File .ReadAllText("CustomDataType.xml");
         CustomDataType  objectData = xmlString.DeserializeXML<CustomDataType>();
 
         Console.WriteLine("CustomDataType.DateTimeMember: "  + objectData.DateTimeMember);
         Console.WriteLine("CustomDataType.IntMember: "  + objectData.IntMember.ToString());
         Console.WriteLine("CustomDataType.StringMember: "  + objectData.StringMember);
 
         Console.WriteLine();
         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
     }
 }

DeserializationGenericExtension

The code snippet listed above illustrates how the DeserializeXML extension discussed earlier now appears as a member method of the string type. Xml data read from the file system is “passed” to the DeserializeXML extension method, specifying <CustomDataType> is to be used as the generic type parameter implemented when performing deserialization.

C# How to: Implementing Xml Serialization through a generic extension method

Article purpose

The purpose of this article is to explore the implementation of object Xml serialization by means of a single extension method supporting generic types.

Sample source code

This article is accompanied by a sample source code Visual Studio project which is available for download here.

Example custom data type

The sample source code provided with this article provides a user defined data type, the CustomDataType class of which the code snippet is listed below.

 public class  CustomDataType
 {
     private  int intMember = 0;
     public  int IntMember
     {
         get  { return intMember; }
         set  { intMember = value ; }
     }
 
     private  string  stringMember = String.Empty;
     public  string  StringMember
     {
         get { return stringMember; }
         set { stringMember = value ; }
     }
 
     private  DateTime dateTimeMember = DateTime.MinValue;
     public  DateTime  DateTimeMember
     {
         get { return  dateTimeMember; }
         set { dateTimeMember = value ; }
     }
 }

This article’s accompanying sample source code was implemented to serialize an object instance of type CustomDataType. The resulting Xml markup representation is listed below.

 <?xml version= "1.0" encoding="utf-16"?>
 <CustomDataType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd= "http://www.w3.org/2001/XMLSchema">
   <IntMember>42</IntMember>
   <StringMember>Some random string</StringMember>
   <DateTimeMember>2013-02-03T17:01:32.9799772+02:00</DateTimeMember>
 </CustomDataType>

The serialization method – Implementation as an extension method with generic type support

Extension method architecture enables developers to create methods which, from a syntactic and implementation point of view appear to be part of an existing data type. Extension methods create the perception of being updates or additions, literarily extending a data type as the name implies. Extension methods do not require access to the source code of the particular types being extended, nor does the implementation thereof require recompilation of the referenced types.

This article illustrates a combined implementation of extension methods extending the functionality of generic types. The following code snippet provides the extension method definition.

 public static class  ExtObject
 {
     public static string XmlSerialize<T>(this T objectToSerialize)
     {
         XmlSerializer xmlSerializer = new XmlSerializer(typeof (T));
 
         StringWriter  stringWriter = new  StringWriter ();
         XmlTextWriter  xmlWriter = new  XmlTextWriter(stringWriter);
 
         xmlWriter.Formatting = Formatting.Indented;
         xmlSerializer.Serialize(xmlWriter, objectToSerialize);
 
         return  stringWriter.ToString();
     }
 }

The XmlSerialize method satisfies the requirements of the extension method architecture by being defined as a static method, implemented as a member method of a statically defined class. In addition the method signature features the this keyword preceding all other method parameters. The seemingly contradicting statement of specifying the this keyword in a static context usually serves as a quick indication that a method is implemented as an extension method. Remember that the this keyword provides a reference to the current instance, whereas in the case of static methods and classes there is no current instance, being static results in limiting a type to only one instance accessed as a shared reference.

The definition of the XmlSerialize method also specifies the definition of a generic type <T>. When defining an extension method the first parameter specified indicates the type being extended. As an example, if an extension method definition specifies as a first parameter a variable of type string, the extension method will operate as an extension to the String class. Notice that extending a native value type is possible as a result of .net’s boxing and unboxing functionality.

The XmlSerialize method defines as a first parameter a variable of generic type <T>. Extending a generic type allows the implementing code access to the XmlSerialize method as a member of all data types, except static types. It is not possible to extend a static type.

The implementation

The XmlSerialize method discussed in the previous section appears as a member method to all non static types, provided that the implementing code applies the relevant namespace resolution by specifying the using statement where needed.

 static void Main(string [] args)
 {
     CustomDataType objectInstance = new CustomDataType();
     objectInstance.DateTimeMember = DateTime.Now;
     objectInstance.IntMember = 42;
     objectInstance.StringMember = "Some random string";
 
     string xmlString = objectInstance.XmlSerialize();
 
     Console.WriteLine(xmlString);
 
     Console.WriteLine();
     Console.WriteLine();
     Console.WriteLine("Press any key..." );
     Console.ReadKey();
 }

SerializationGenericExtension

From the code listed above the XmlSerialize method appears as a member of the CustomDataType class but in reality CustomDataType does not define the XmlSerialize method. The type being extended functions as per normal, not being aware of the extension method XmlSerialize.

The extension method now provides a uniform implementation enabling objects to be serialized to an Xml string, regardless of type.

Note: Not all types can be serialized! A commonly repeated mistake regarding object Xml serialization being that serialization will fail if a type does not provide a constructor with no parameters.

Extending ConfigurationManager – Code Sample

Extending ConfigurationManager – Get values by type. Short Code Sample explaining how to read values from Application Configuration Files without having to cast/parse by hand.
Extending ConfigurationManager


Dewald Esterhuizen

Blog Stats

  • 437,835 hits

Enter your email address to follow and receive notifications of new posts by email.

Join 204 other followers

Archives

Twitter feed


%d bloggers like this: