PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/otp.net/Otp/Erlang/CloneObject.cs

https://github.com/babo/jungerl
C# | 113 lines | 67 code | 16 blank | 30 comment | 13 complexity | e35def62878801c510bf3a31d05e52f0 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. using System;
  2. using System.Reflection;
  3. using System.Collections;
  4. namespace Amir_Harel.Cloning
  5. {
  6. /// <summary>
  7. /// <b>BaseObject</b> class is an abstract class for you to derive from. <br>
  8. /// Every class that will be dirived from this class will support the <b>Clone</b> method automaticly.<br>
  9. /// The class implements the interface <i>ICloneable</i> and there for every object that will be derived <br>
  10. /// from this object will support the <i>ICloneable</i> interface as well.
  11. /// </summary>
  12. public abstract class BaseObject : ICloneable
  13. {
  14. /// <summary>
  15. /// Clone the object, and returning a reference to a cloned object.
  16. /// </summary>
  17. /// <returns>Reference to the new cloned object.</returns>
  18. public object Clone()
  19. {
  20. //First we create an instance of this specific type.
  21. object newObject = Activator.CreateInstance( this.GetType() );
  22. //We get the array of fields for the new type instance.
  23. FieldInfo[] fields = newObject.GetType().GetFields();
  24. int i = 0;
  25. foreach( FieldInfo fi in this.GetType().GetFields() )
  26. {
  27. //We query if the fiels support the ICloneable interface.
  28. Type ICloneType = fi.FieldType.GetInterface( "ICloneable" , true );
  29. if( ICloneType != null )
  30. {
  31. //Getting the ICloneable interface from the object.
  32. ICloneable IClone = (ICloneable)fi.GetValue(this);
  33. //We use the clone method to set the new value to the field.
  34. fields[i].SetValue( newObject , IClone.Clone() );
  35. }
  36. else
  37. {
  38. //If the field doesn't support the ICloneable interface then just set it.
  39. fields[i].SetValue( newObject , fi.GetValue(this) );
  40. }
  41. //Now we check if the object support the IEnumerable interface, so if it does
  42. //we need to enumerate all its items and check if they support the ICloneable interface.
  43. Type IEnumerableType = fi.FieldType.GetInterface( "IEnumerable" , true );
  44. if( IEnumerableType != null )
  45. {
  46. //Get the IEnumerable interface from the field.
  47. IEnumerable IEnum = (IEnumerable)fi.GetValue(this);
  48. //This version support the IList and the IDictionary interfaces to iterate
  49. //on collections.
  50. Type IListType = fields[i].FieldType.GetInterface( "IList" , true );
  51. Type IDicType = fields[i].FieldType.GetInterface( "IDictionary" , true );
  52. int j = 0;
  53. if( IListType != null )
  54. {
  55. //Getting the IList interface.
  56. IList list = (IList)fields[i].GetValue(newObject);
  57. foreach( object obj in IEnum )
  58. {
  59. //Checking to see if the current item support the ICloneable interface.
  60. ICloneType = obj.GetType().GetInterface( "ICloneable" , true );
  61. if( ICloneType != null )
  62. {
  63. //If it does support the ICloneable interface, we use it to set the clone of
  64. //the object in the list.
  65. ICloneable clone = (ICloneable)obj;
  66. list[j] = clone.Clone();
  67. }
  68. //NOTE: If the item in the list is not support the ICloneable interface then
  69. // in the cloned list this item will be the same item as in the original list
  70. //(as long as this type is a reference type).
  71. j++;
  72. }
  73. }
  74. else if( IDicType != null )
  75. {
  76. //Getting the dictionary interface.
  77. IDictionary dic = (IDictionary)fields[i].GetValue(newObject);
  78. j = 0;
  79. foreach( DictionaryEntry de in IEnum )
  80. {
  81. //Checking to see if the item support the ICloneable interface.
  82. ICloneType = de.Value.GetType().GetInterface( "ICloneable" , true );
  83. if( ICloneType != null )
  84. {
  85. ICloneable clone = (ICloneable)de.Value;
  86. dic[de.Key] = clone.Clone();
  87. }
  88. j++;
  89. }
  90. }
  91. }
  92. i++;
  93. }
  94. return newObject;
  95. }
  96. }
  97. }