The Labs \ Source Viewer \ SSCLI \ System \ ValueType

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Class:  ValueType
  18. **
  19. **
  20. ** Purpose: Base class for all value classes.
  21. **
  22. **
  23. ===========================================================*/
  24. namespace System
  25. {
  26.     using System;
  27.     using System.Reflection;
  28.     using System.Runtime.CompilerServices;
  29.    
  30.     [Serializable()]
  31.     [System.Runtime.InteropServices.ComVisible(true)]
  32.     public abstract class ValueType
  33.     {
  34.        
  35.         public override bool Equals(object obj)
  36.         {
  37.             BCLDebug.Perf(false, "ValueType::Equals is not fast. " + this.GetType().FullName + " should override Equals(Object)");
  38.             if (null == obj) {
  39.                 return false;
  40.             }
  41.             RuntimeType thisType = (RuntimeType)this.GetType();
  42.             RuntimeType thatType = (RuntimeType)obj.GetType();
  43.            
  44.             if (thatType != thisType) {
  45.                 return false;
  46.             }
  47.            
  48.             object thisObj = (object)this;
  49.             object thisResult;
  50.             object thatResult;
  51.            
  52.             // if there are no GC references in this object we can avoid reflection
  53.             // and do a fast memcmp
  54.             if (CanCompareBits(this))
  55.                 return FastEqualsCheck(thisObj, obj);
  56.            
  57.             FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  58.            
  59.             for (int i = 0; i < thisFields.Length; i++) {
  60.                 thisResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(thisObj, false);
  61.                 thatResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(obj, false);
  62.                
  63.                 if (thisResult == null) {
  64.                     if (thatResult != null)
  65.                         return false;
  66.                 }
  67.                 else if (!thisResult.Equals(thatResult)) {
  68.                     return false;
  69.                 }
  70.             }
  71.            
  72.             return true;
  73.         }
  74.        
  75.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  76.         private static extern bool CanCompareBits(object obj);
  77.        
  78.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  79.         private static extern bool FastEqualsCheck(object a, object b);
  80.        
  81. /*=================================GetHashCode==================================
  82.         **Action: Our algorithm for returning the hashcode is a little bit complex.  We look
  83.         **        for the first non-static field and get it's hashcode.  If the type has no
  84.         **        non-static fields, we return the hashcode of the type.  We can't take the
  85.         **        hashcode of a static member because if that member is of the same type as
  86.         **        the original type, we'll end up in an infinite loop.
  87.         **Returns: The hashcode for the type.
  88.         **Arguments: None.
  89.         **Exceptions: None.
  90.         ==============================================================================*/       
  91.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  92.         public override extern int GetHashCode();
  93.        
  94.         public override string ToString()
  95.         {
  96.             return this.GetType().ToString();
  97.         }
  98.     }
  99. }

Developer Fusion