NHibernate 등 DDD 패턴에서 고유한 HashCode 값 생성이 상당히 중요합니다. 이를 위해 제작한 클래스이고, 현재까지 잘 작동하는 코드입니다.^^
using System;
using System.Linq;
using System.Linq.Expressions;
using RCL.LinqExtensions;
namespace RCL.Core
{
///
/// HashCode 를 생성해주는 Tool Class 입니다.
///
public static class HashTool
{
private const int Factor = 31;
private const int InitValue = 1;
public const int NullValue = 0;
private static readonly int EmptyStringHashCode = string.Empty.GetHashCode();
///
/// 지정된 객체들의 HashCode를 계산합니다.
///
public static int Compute(object obj)
{
return (obj != null) ? obj.GetHashCode() : NullValue;
}
///
/// 지정된 객체들의 HashCode를 계산합니다.
///
public static int Compute(object obj1, object obj2)
{
return Compute(obj1) * Factor + Compute(obj2);
}
///
/// 지정된 객체들의 HashCode를 계산합니다.
///
public static int Compute(object obj1, object obj2, object obj3)
{
return Compute(obj1, obj2) * Factor + Compute(obj3);
}
///
/// 지정된 객체들의 HashCode를 계산합니다.
///
public static int Compute(object obj1, object obj2, object obj3, object obj4)
{
return Compute(obj1, obj2, obj3) * Factor + Compute(obj4);
}
///
/// 지정된 객체들의 HashCode를 계산합니다.
///
/// 객체를 입력하세요 (GetHashCode를 넣지 마세요)
///
public static int Compute(params object[] objs)
{
int hash = NullValue;
if(objs != null)
foreach(var obj in objs)
hash = hash * Factor + Compute(obj);
return hash;
}
///
/// 문자열의 HashCode를 반환합니다. null 이거나 빈문자열이면 string.Empty.GetHashCode() 값을 반환합니다. (0은 아닙니다)
///
///
///
public static int CalcHash(this string str)
{
return str.IsEmpty() ? EmptyStringHashCode : str.GetHashCode();
}
///
/// 인스턴스의 특정 속성들로부터 HashCode를 생성합니다.
///
/// 대상 객체의 수형
/// 해시코드를 얻고자하는 대상 객체
/// 해시코드 조합용 속성들
///
public static int CalcHash(this T target, params Expression>[] propertyExprs)
{
if(Equals(target, default(T)))
return 0;
#if !SILVERLIGHT
if(propertyExprs == null || propertyExprs.Length == 0)
return target.GetHashCode();
var propertyNames = propertyExprs.Select(expr => expr.Body.FindMemberName()).ToArray();
var accessor = DynamicAccessorFactory.CreateDynamicAccessor(MapPropertyOptions.Safety);
return Compute(propertyNames.Select(name => accessor.GetPropertyValue(target, name)).ToArray());
#else
return target.GetHashCode();
#endif
}
}
}
HTML 코드에서 글을 써야 해서 좀 문제가 있네요^^
댓글 없음:
댓글 쓰기