[ http://issues.apache.org/jira/browse/IBATISNET-119?page=all ]
     
Gilles Bayon resolved IBATISNET-119:
------------------------------------

    Fix Version: DataMapper 1.3
     Resolution: Fixed

In SVN

> CacheKey.Equals(object)/HashCode issue still a problem (was IBATISNET-118)
> --------------------------------------------------------------------------
>
>          Key: IBATISNET-119
>          URL: http://issues.apache.org/jira/browse/IBATISNET-119
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> The fix for IBATISNET-118 does not address the issue (just hides it in one 
> particular instance).  
> The issue is that you can not use HashCodes to determine object equality.  
> Unique objects do not always have unique HashCodes (no matter how hard you 
> try).  There just aren't enough hashcodes to go around :)
> I understand why my previous 'patch' wasn't accepted (didn't expect it to 
> be).  Since we are not using an object's own "GetHashCode()" to get it's 
> hashcode, we can not use it's own "Equals" to determine equality.  So we 
> really have to do is create a new method on ObjectProbe that compares two 
> objects in much the same way that ObjectProbe generates hashcodes.  I was 
> just too lazy to write it yesterday :)
> Here is an updated unit test and a potential fix...
> --- BEGIN UNIT TEST ---
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataMapper.Test.NUnit.SqlMapTests
> {
>       [TestFixture]
>       public class CacheKeyTest
>       {
>               [Test]
>               public void 
> ShouldNotConsider1LAndNegative9223372034707292159LToBeEqual()
>               {
>                       // old version of ObjectProbe gave TestClass based on 
> these longs the same HashCode
>                       DoTestClassEquals(1L, -9223372034707292159L);
>               }
>               [Test]
>               public void 
> ShouldNotConsider1LAndNegative9223372036524971138LToBeEqual()
>               {
>                       // current version of ObjectProbe gives TestClass based 
> on these longs the same HashCode
>                       DoTestClassEquals(1L, -9223372036524971138L);
>               }
>               private static void DoTestClassEquals(long firstLong, long 
> secondLong)
>               {
>                       TypeHandlerFactory factory = new TypeHandlerFactory();
>       
>                       // Two cache keys are equal except for the parameter.
>                       CacheKey key = new CacheKey(factory, "STATEMENT", 
> "SQL", new TestClass(firstLong), new string[] {"AProperty"}, 0, 0, 
> CacheKeyType.Object);
>                       CacheKey aDifferentKey = new CacheKey(factory, 
> "STATEMENT", "SQL", new TestClass(secondLong), new string[] {"AProperty"}, 0, 
> 0, CacheKeyType.Object);
>       
>                       Assert.IsFalse(aDifferentKey.Equals(key)); // should 
> not be equal.
>               }
>               private class TestClass
>               {
>                       private long _property = long.MinValue;
>                       public TestClass(long aProperty)
>                       {
>                               _property = aProperty;
>                       }
>                       public long AProperty
>                       {
>                               get { return _property; }
>                               set { _property = value; }
>                       }
>               }
>       }
> }
> --- END UNIT TEST ---
> FIX (not sure if this will break other parts of the system... but it 
> shouldn't):
> --- BEGIN ObjectProbe ---
> #region Apache Notice
> /*****************************************************************************
>  * $Header: $
>  * $Revision: $
>  * $Date: $
>  * 
>  * iBATIS.NET Data Mapper
>  * Copyright (C) 2004 - Gilles Bayon
>  *  
>  * 
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  * 
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  * 
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  * 
>  
> ********************************************************************************/
> #endregion
> using System;
> using System.Collections;
> using System.Reflection;
> using IBatisNet.Common.Exceptions;
> namespace IBatisNet.Common.Utilities.Objects
> {
>       /// <summary>
>       /// Description résumée de ObjectProbe.
>       /// </summary>
>       public class ObjectProbe
>       {
>               private static ArrayList _simpleTypeMap = new ArrayList();
>               static ObjectProbe() 
>               {
>                       _simpleTypeMap.Add(typeof(string));
>                       _simpleTypeMap.Add(typeof(Byte));
>                       _simpleTypeMap.Add(typeof(Int16));
>                       _simpleTypeMap.Add(typeof(char));
>                       _simpleTypeMap.Add(typeof(Int32));
>                       _simpleTypeMap.Add(typeof(Int64));
>                       _simpleTypeMap.Add(typeof(Single));
>                       _simpleTypeMap.Add(typeof(Double));
>                       _simpleTypeMap.Add(typeof(Boolean));
>                       _simpleTypeMap.Add(typeof(DateTime));
>                       _simpleTypeMap.Add(typeof(Decimal));
>                       //                      
> _simpleTypeMap.Add(typeof(Hashtable));
>                       //                      
> _simpleTypeMap.Add(typeof(SortedList));
>                       //                      
> _simpleTypeMap.Add(typeof(ArrayList));
>                       //                      
> _simpleTypeMap.Add(typeof(Array));
>                       //                      
> simpleTypeMap.Add(LinkedList.class);
>                       //                      
> simpleTypeMap.Add(HashSet.class);
>                       //                      
> simpleTypeMap.Add(TreeSet.class);
>                       //                      simpleTypeMap.Add(Vector.class);
>                       //                      
> simpleTypeMap.Add(Hashtable.class);
>                       _simpleTypeMap.Add(typeof(SByte));
>                       _simpleTypeMap.Add(typeof(UInt16));
>                       _simpleTypeMap.Add(typeof(UInt32));
>                       _simpleTypeMap.Add(typeof(UInt64));
>                       _simpleTypeMap.Add(typeof(IEnumerator));
>               }
>               /// <summary>
>               /// Returns an array of the readable properties names exposed 
> by an object
>               /// </summary>
>               /// <param name="obj">The object</param>
>               /// <returns>The properties name</returns>
>               public static string[] GetReadablePropertyNames(object obj) 
>               {
>                       return 
> ReflectionInfo.GetInstance(obj.GetType()).GetReadablePropertyNames();
>               }
>       
>               /// <summary>
>               /// Returns an array of the writeable properties name exposed 
> by a object
>               /// </summary>
>               /// <param name="obj">The object</param>
>               /// <returns>The properties name</returns>
>               public static string[] GetWriteablePropertyNames(object obj) 
>               {
>                       return 
> ReflectionInfo.GetInstance(obj.GetType()).GetWriteablePropertyNames();
>               }
>               /// <summary>
>               ///  Returns the type that the set expects to receive as a 
> parameter when
>               ///  setting a property value.
>               /// </summary>
>               /// <param name="obj">The object to check</param>
>               /// <param name="propertyName">The name of the property</param>
>               /// <returns>The type of the property</returns>
>               private static Type GetPropertyTypeForSetter(object obj, string 
> propertyName) 
>               {
>                       Type type = obj.GetType();
>                       if (obj is IDictionary) 
>                       {
>                               IDictionary map = (IDictionary) obj;
>                               object value = map[propertyName];
>                               if (value == null) 
>                               {
>                                       type = typeof(object);
>                               } 
>                               else 
>                               {
>                                       type = value.GetType();
>                               }
>                       } 
>                       else 
>                       {
>                               if (propertyName.IndexOf('.') > -1) 
>                               {
>                                       StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                                       IEnumerator enumerator = 
> parser.GetEnumerator();
>                                       while (enumerator.MoveNext()) 
>                                       {
>                                               propertyName = 
> (string)enumerator.Current;
>                                               type = 
> ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
>                                       }
>                               } 
>                               else 
>                               {
>                                       type = 
> ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
>                               }
>                       }
>                       return type;
>               }
>               /// <summary>
>               ///  Returns the type that the set expects to receive as a 
> parameter when
>               ///  setting a property value.
>               /// </summary>
>               /// <param name="type">The type to check</param>
>               /// <param name="propertyName">The name of the property</param>
>               /// <returns>The type of the property</returns>
>               private static Type GetPropertyTypeForSetter(Type type, string 
> propertyName) 
>               {
>                       if (propertyName.IndexOf('.') > -1) 
>                       {
>                               StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                               IEnumerator enumerator = parser.GetEnumerator();
>                               while (enumerator.MoveNext()) 
>                               {
>                                       propertyName = 
> (string)enumerator.Current;
>                                       type = 
> ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
>                               }
>                       } 
>                       else 
>                       {
>                               type = 
> ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
>                       }
>                       return type;
>               }
>               /// <summary>
>               ///  Returns the type that the get expects to receive as a 
> parameter when
>               ///  setting a property value.
>               /// </summary>
>               /// <param name="obj">The object to check</param>
>               /// <param name="propertyName">The name of the property</param>
>               /// <returns>The type of the property</returns>
>               public static Type GetPropertyTypeForGetter(object obj, string 
> propertyName) 
>               {
>                       Type type = obj.GetType();
>                       if (obj is IDictionary) 
>                       {
>                               IDictionary map = (IDictionary) obj;
>                               object value = map[propertyName];
>                               if (value == null) 
>                               {
>                                       type = typeof(object);
>                               } 
>                               else 
>                               {
>                                       type = value.GetType();
>                               }
>                       } 
>                       else 
>                       {
>                               if (propertyName.IndexOf('.') > -1) 
>                               {
>                                       StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                                       IEnumerator enumerator = 
> parser.GetEnumerator();
>                                       while (enumerator.MoveNext()) 
>                                       {
>                                               propertyName = 
> (string)enumerator.Current;
>                                               type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                                       }
>                               } 
>                               else 
>                               {
>                                       type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                               }
>                       }
>                       return type;
>               }
>               /// <summary>
>               ///  Returns the type that the get expects to receive as a 
> parameter when
>               ///  setting a property value.
>               /// </summary>
>               /// <param name="type">The type to check</param>
>               /// <param name="propertyName">The name of the property</param>
>               /// <returns>The type of the property</returns>
>               public static Type GetPropertyTypeForGetter(Type type, string 
> propertyName) 
>               {
>                       if (propertyName.IndexOf('.') > -1) 
>                       {
>                               StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                               IEnumerator enumerator = parser.GetEnumerator();
>                               while (enumerator.MoveNext()) 
>                               {
>                                       propertyName = 
> (string)enumerator.Current;
>                                       type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                               }
>                       } 
>                       else 
>                       {
>                               type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                       }
>                       return type;
>               }
>               private static object GetArrayProperty(object obj, string 
> indexedName) 
>               {
>                       object value = null;
>                       try 
>                       {
>                               int startIndex  = indexedName.IndexOf("[");
>                               int length = indexedName.IndexOf("]");
>                               string name = indexedName.Substring(0, 
> startIndex);
>                               string index = indexedName.Substring( 
> startIndex+1, length-(startIndex+1));
>                               int i = System.Convert.ToInt32(index);
>                               
>                               if (name.Length > 0)
>                               {
>                                       value = GetProperty(obj, name);
>                               }
>                               else
>                               {
>                                       value = obj;
>                               }
>                               if (value is IList) 
>                               {
>                                       value = ((IList) value)[i];
>                               } 
>                               else 
>                               {
>                                       throw new ProbeException("The '" + name 
> + "' property of the " + obj.GetType().Name + " class is not a List or 
> Array.");
>                               }
>                       }
>                       catch (ProbeException pe) 
>                       {
>                               throw pe;
>                       } 
>                       catch(Exception e)
>                       {               
>                               throw new ProbeException("Error getting ordinal 
> value from .net object. Cause" + e.Message, e);
>                       }
>                       return value;
>               }
>               /// <summary>
>               /// 
>               /// </summary>
>               /// <param name="obj"></param>
>               /// <param name="propertyName"></param>
>               /// <returns></returns>
>               protected static object GetProperty(object obj, string 
> propertyName) 
>               {
>                       ReflectionInfo reflectionCache = 
> ReflectionInfo.GetInstance(obj.GetType());
>                       try 
>                       {
>                               object value = null;
>                               if (propertyName.IndexOf("[") > -1) 
>                               {
>                                       value = GetArrayProperty(obj, 
> propertyName);
>                               } 
>                               else 
>                               {
>                                       if (obj is IDictionary) 
>                                       {
>                                               value = ((IDictionary) 
> obj)[propertyName];
>                                       } 
>                                       else 
>                                       {
>                                               PropertyInfo propertyInfo = 
> reflectionCache.GetGetter(propertyName);
>                                               if (propertyInfo == null) 
>                                               {
>                                                       throw new 
> ProbeException("No Get method for property " + propertyName + " on instance 
> of " + obj.GetType().Name);
>                                               }
>                                               try 
>                                               {
>                                                       value = 
> propertyInfo.GetValue(obj, null);
>                                               } 
>                                               catch (ArgumentException ae) 
>                                               {
>                                                       throw new 
> ProbeException(ae);
>                                               }
>                                               catch (TargetException t) 
>                                               {
>                                                       throw new 
> ProbeException(t);
>                                               }
>                                               catch 
> (TargetParameterCountException tp) 
>                                               {
>                                                       throw new 
> ProbeException(tp);
>                                               }
>                                               catch (MethodAccessException 
> ma) 
>                                               {
>                                                       throw new 
> ProbeException(ma);
>                                               }                               
>                 
>                                       }
>                               }
>                               return value;
>                       } 
>                       catch (ProbeException pe) 
>                       {
>                               throw pe;
>                       } 
>                       catch(Exception e)
>                       {
>                               throw new ProbeException("Could not Set 
> property '" + propertyName + "' for " + obj.GetType().Name + ".  Cause: " + 
> e.Message, e);
>                       }
>               }
>               private static void SetArrayProperty(object obj, string 
> indexedName, object value) 
>               {
>                       try 
>                       {
>                               int startIndex  = indexedName.IndexOf("[");
>                               int length = indexedName.IndexOf("]");
>                               string name = indexedName.Substring(0, 
> startIndex);
>                               string index = indexedName.Substring( 
> startIndex+1, length-(startIndex+1));
>                               int i = System.Convert.ToInt32(index);
>                               
>                               object list = null;
>                               if (name.Length > 0)
>                               {
>                                       list = GetProperty(obj, name);
>                               }
>                               else
>                               {
>                                       list = obj;
>                               }
>                               if (list is IList) 
>                               {
>                                       ((IList) list)[i] = value;
>                               } 
>                               else 
>                               {
>                                       throw new ProbeException("The '" + name 
> + "' property of the " + obj.GetType().Name + " class is not a List or 
> Array.");
>                               }
>                       } 
>                       catch (ProbeException pe) 
>                       {
>                               throw pe;
>                       } 
>                       catch (Exception e) 
>                       {
>                               throw new ProbeException("Error getting ordinal 
> value from .net object. Cause" + e.Message, e);
>                       }
>               }
>               /// <summary>
>               /// 
>               /// </summary>
>               /// <param name="obj"></param>
>               /// <param name="propertyName"></param>
>               /// <param name="propertyValue"></param>
>               protected static void SetProperty(object obj, string 
> propertyName, object propertyValue)
>               {
>                       ReflectionInfo reflectionCache = 
> ReflectionInfo.GetInstance(obj.GetType());
>                       try 
>                       {
>                               if (propertyName.IndexOf("[") > -1) 
>                               {
>                                       SetArrayProperty(obj, propertyName, 
> propertyValue);
>                               } 
>                               else 
>                               {
>                                       if (obj is IDictionary) 
>                                       {
>                                               ((IDictionary) 
> obj)[propertyName] = propertyValue;
>                                       } 
>                                       else 
>                                       {
>                                               PropertyInfo propertyInfo = 
> reflectionCache.GetSetter(propertyName);
>                                               
>                                               if (propertyInfo == null) 
>                                               {
>                                                       throw new 
> ProbeException("No Set method for property " + propertyName + " on instance 
> of " + obj.GetType().Name);
>                                               }
>                                               try 
>                                               {
>                                                       
> propertyInfo.SetValue(obj, propertyValue, null);
>                                               }
>                                               catch (ArgumentException ae) 
>                                               {
>                                                       throw new 
> ProbeException(ae);
>                                               }
>                                               catch (TargetException t) 
>                                               {
>                                                       throw new 
> ProbeException(t);
>                                               }
>                                               catch 
> (TargetParameterCountException tp) 
>                                               {
>                                                       throw new 
> ProbeException(tp);
>                                               }
>                                               catch (MethodAccessException 
> ma) 
>                                               {
>                                                       throw new 
> ProbeException(ma);
>                                               }                               
>                 
>                                       }
>                               }
>                       }
>                       catch (ProbeException pe) 
>                       {
>                               throw pe;
>                       } 
>                       catch (Exception e) 
>                       {
>                               throw new ProbeException("Could not Get 
> property '" + propertyName + "' for " + obj.GetType().Name + ".  Cause: " + 
> e.Message, e);
>                       }
>               }
>               /// <summary>
>               /// Return the specified property on an object. 
>               /// </summary>
>               /// <param name="obj">The Object on which to invoke the 
> specified property.</param>
>               /// <param name="propertyName">The name of the property.</param>
>               /// <returns>An Object representing the return value of the 
> invoked property.</returns>
>               public static object GetPropertyValue(object obj, string 
> propertyName) 
>               {
>                       if (propertyName.IndexOf('.') > -1) 
>                       {
>                               StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                               IEnumerator enumerator = parser.GetEnumerator();
>                               object value = obj;
>                               string token = null;
>                               while (enumerator.MoveNext()) 
>                               {
>                                       token = (string)enumerator.Current;
>                                       value = GetProperty(value, token);
>                                       if (value == null) 
>                                       {
>                                               break;
>                                       }
>                               }
>                               return value;
>                       } 
>                       else 
>                       {
>                               return GetProperty(obj, propertyName);
>                       }
>               }
>               /// <summary>
>               /// Set the specified property on an object 
>               /// </summary>
>               /// <param name="obj">The Object on which to invoke the 
> specified property.</param>
>               /// <param name="propertyName">The name of the property to 
> set.</param>
>               /// <param name="propertyValue">The new value to set.</param>
>               public static void SetPropertyValue(object obj, string 
> propertyName, object propertyValue)
>               {
>                       if (propertyName.IndexOf('.') > -1) 
>                       {
>                               StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                               IEnumerator enumerator = parser.GetEnumerator();
>                               enumerator.MoveNext();
>                               string currentPropertyName = 
> (string)enumerator.Current;
>                               object child = obj;
>       
>                               while (enumerator.MoveNext()) 
>                               {
>                                       Type type = 
> GetPropertyTypeForSetter(child, currentPropertyName);
>                                       object parent = child;
>                                       child = GetProperty(parent, 
> currentPropertyName);
>                                       if (child == null) 
>                                       {
>                                               try 
>                                               {
>                                                       child = 
> Activator.CreateInstance(type);
>                                                       
> SetPropertyValue(parent, currentPropertyName, child);
>                                               } 
>                                               catch (Exception e) 
>                                               {
>                                                       throw new 
> ProbeException("Cannot set value of property '" + propertyName + "' because 
> '" + currentPropertyName + "' is null and cannot be instantiated on instance 
> of " + type.Name + ". Cause:" + e.Message, e);
>                                               }
>                                       }
>                                       currentPropertyName = 
> (string)enumerator.Current;
>                               }
>                               SetProperty(child, currentPropertyName, 
> propertyValue);
>                       } 
>                       else 
>                       {
>                               SetProperty(obj, propertyName, propertyValue);
>                       }
>               }
>               /// <summary>
>               /// Checks to see if a Object has a writable property/field be 
> a given name
>               /// </summary>
>               /// <param name="obj"> The object to check</param>
>               /// <param name="propertyName">The property to check for</param>
>               /// <returns>True if the property exists and is 
> writable</returns>
>               public static bool HasWritableProperty(object obj, string 
> propertyName) 
>               {
>                       bool hasProperty = false;
>                       if (obj is IDictionary) 
>                       {
>                               hasProperty = ((IDictionary) 
> obj).Contains(propertyName);
>                       } 
>                       else 
>                       {
>                               if (propertyName.IndexOf('.') > -1) 
>                               {
>                                       StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                                       IEnumerator enumerator = 
> parser.GetEnumerator();
>                                       Type type = obj.GetType();
>                                       while (enumerator.MoveNext()) 
>                                       { 
>                                               propertyName = 
> (string)enumerator.Current;
>                                               type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                                               hasProperty = 
> ReflectionInfo.GetInstance(type).HasWritableProperty(propertyName);
>                                       }
>                               } 
>                               else 
>                               {
>                                       hasProperty = 
> ReflectionInfo.GetInstance(obj.GetType()).HasWritableProperty(propertyName);
>                               }
>                       }
>                       return hasProperty;
>               }
>               /// <summary>
>               /// Checks to see if the Object have a property/field be a 
> given name.
>               /// </summary>
>               /// <param name="obj">The Object on which to invoke the 
> specified property.</param>
>               /// <param name="propertyName">The name of the property to 
> check for.</param>
>               /// <returns>
>               /// True or false if the property exists and is readable.
>               /// </returns>
>               public static bool HasReadableProperty(object obj, string 
> propertyName) 
>               {
>                       bool hasProperty = false;
>                       if (obj is IDictionary) 
>                       {
>                               hasProperty = ((IDictionary) 
> obj).Contains(propertyName);
>                       } 
>                       else 
>                       {
>                               if (propertyName.IndexOf('.') > -1) 
>                               {
>                                       StringTokenizer parser = new 
> StringTokenizer(propertyName, ".");
>                                       IEnumerator enumerator = 
> parser.GetEnumerator();
>                                       Type type = obj.GetType();
>                                       while (enumerator.MoveNext()) 
>                                       { 
>                                               propertyName = 
> (string)enumerator.Current;
>                                               type = 
> ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
>                                               hasProperty = 
> ReflectionInfo.GetInstance(type).HasReadableProperty(propertyName);
>                                       }
>                               } 
>                               else 
>                               {
>                                       hasProperty = 
> ReflectionInfo.GetInstance(obj.GetType()).HasReadableProperty(propertyName);
>                               }
>                       }
>                       
>                       return hasProperty;
>               }
>               /// <summary>
>               /// 
>               /// </summary>
>               /// <param name="type"></param>
>               /// <returns></returns>
>               public static bool IsSimpleType(Type type) 
>               {
>                       if (_simpleTypeMap.Contains(type)) 
>                       {
>                               return true;
>                       } 
>                       else if (type.IsSubclassOf(typeof(ICollection)))
>                       {
>                               return true;
>                       } 
>                       else if (type.IsSubclassOf(typeof(IDictionary))) 
>                       {
>                               return true;
>                       } 
>                       else if (type.IsSubclassOf(typeof(IList))) 
>                       {
>                               return true;
>                       } 
>                       else if (type.IsSubclassOf(typeof(IEnumerable))) 
>                       {
>                               return true;
>                       } 
>                       else
>                       {
>                               return false;
>                       }
>               }
>               /// <summary>
>               ///  Calculates a hash code for all readable properties of a 
> object.
>               /// </summary>
>               /// <param name="obj">The object to calculate the hash code 
> for.</param>
>               /// <returns>The hash code.</returns>
>               public static int ObjectHashCode(object obj)
>               {
>                       return ObjectHashCode(obj, 
> GetReadablePropertyNames(obj));
>               }
>               public static int ObjectHashCode(object obj, string[] 
> properties) 
>               {
>                       ArrayList values = UnwrapObjectDownToSimpleTypes(obj, 
> properties);
>                       int hashCode = obj.GetType().FullName.GetHashCode();
>                       foreach (object simpleObject in values)
>                       {
>                               if (simpleObject != null)
>                               {
>                                       hashCode += simpleObject.GetHashCode();
>                                       hashCode += 
> simpleObject.ToString().GetHashCode();
>                                       hashCode *= 29;
>                               }
>                       }
>                       return hashCode;
>               }
>               public static bool AreObjectsEqual(object obj1, object obj2)
>               {
>                       return AreObjectsEqual(obj1, obj2, 
> GetReadablePropertyNames(obj1));
>               }
>               public static bool AreObjectsEqual(object obj1, object obj2, 
> string[] properties)
>               {
>                       if (obj1 == null && obj2 != null)
>                               return false;
>                       if (obj1 != null && obj2 == null)
>                               return false;
>                       if (obj1 == null && obj2 == null)
>                               return true;
>                       if (obj1.GetType() != obj2.GetType())
>                               return false;
>                       ArrayList obj1Values = 
> UnwrapObjectDownToSimpleTypes(obj1, properties);
>                       ArrayList obj2Values = 
> UnwrapObjectDownToSimpleTypes(obj2, properties);
>                       if (obj1Values.Count != obj2Values.Count)
>                               return false;
>                       for (int i = 0; i < obj1Values.Count; i++)
>                       {
>                               if (obj1Values[i] != obj2Values[i])
>                                       return false;
>                       }
>                       return true;
>               }
>               public static ArrayList UnwrapObjectDownToSimpleTypes(object 
> obj, ArrayList objectValues)
>               {
>                       return UnwrapObjectDownToSimpleTypes(obj, 
> GetReadablePropertyNames(obj), objectValues);
>               }
>               public static ArrayList UnwrapObjectDownToSimpleTypes(object 
> obj, string[] properties)
>               {
>                       return UnwrapObjectDownToSimpleTypes(obj, properties, 
> new ArrayList());
>               }
>               public static ArrayList UnwrapObjectDownToSimpleTypes(object 
> obj, string[] properties, ArrayList objectValues) 
>               {
>                       ArrayList alreadyDigested = new ArrayList();
>                       int hashcode = obj.GetType().FullName.GetHashCode();
>                       for (int i = 0; i < properties.Length; i++) 
>                       {
>                               object value = GetProperty(obj, properties[i]);
>                               if (value != null) 
>                               {
>                                       if (IsSimpleType(value.GetType())) 
>                                       {
>                                               objectValues.Add(value);
>                                       } 
>                                       else 
>                                       {
>                                               // It's a Object 
>                                               // Check to avoid endless loop 
> (circular dependency)
>                                               if (value != obj) 
>                                               {
>                                                       if 
> (!alreadyDigested.Contains(value)) 
>                                                       {
>                                                               
> alreadyDigested.Add(value);
>                                                               
> UnwrapObjectDownToSimpleTypes(value, objectValues);
>                                                       }
>                                               }
>                                       }
>                               }
>                               else
>                               {
>                                       objectValues.Add(null);
>                               }
>                       }
>                       return objectValues;
>               }
>       }
> }
> --- END ObjectProbe  ---
> --- BEGIN CacheKey.Equals(object) ---
>               public override bool Equals(object obj) 
>               {
>                       //-----------------------------------
>                       if (this == obj) return true;
>                       if (!(obj is CacheKey)) return false;
>                       CacheKey cacheKey = (CacheKey)obj;
>                       if (_maxResults != cacheKey._maxResults) return false;
>                       if (_skipRecords != cacheKey._skipRecords) return false;
>                       if (_type != cacheKey._type) return false;
>                       if (_parameter is Hashtable) 
>                       {
>                               if (_hashCode != cacheKey._hashCode) return 
> false;
>                               if (!_parameter.Equals(cacheKey._parameter)) 
> return false;
>                       } 
>                       else if (_parameter != null && 
> _typeHandlerFactory.IsSimpleType(_parameter.GetType())) 
>                       {
>                               if (_parameter != null ? 
> !_parameter.Equals(cacheKey._parameter) : cacheKey._parameter != null) return 
> false;
>                       } 
>                       else 
>                       {
>                               if (!ObjectProbe.AreObjectsEqual(_parameter, 
> cacheKey._parameter, _properties))
>                               {
>                                       return false;
>                               }
>                       }
>                       if (_sql != null ? !_sql.Equals(cacheKey._sql) : 
> cacheKey._sql != null) return false;
>                       return true;
>               }
> --- END CacheKey.Equals(object) ---

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to