C#/Winform

[C#] Property 비교 함수

kjun.kr 2022. 3. 30. 15:46
728x90
728x170
    public static class ProjectExtension
    {
        /// <summary>
        /// Properties 의 동일여부
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="self"></param>
        /// <param name="to"></param>
        /// <param name="ignore"></param>
        /// <returns></returns>
        public static bool PropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
        {
            if (self != null && to != null)
            {
                var type = typeof(T);
                var ignoreList = new List<string>(ignore);
                var unequalProperties =
                    from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                    where !ignoreList.Contains(pi.Name) && pi.GetUnderlyingType().IsSimpleType() && pi.GetIndexParameters().Length == 0
                    let selfValue = type.GetProperty(pi.Name).GetValue(self, null)
                    let toValue = type.GetProperty(pi.Name).GetValue(to, null)
                    where selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue))
                    select selfValue;
                return !unequalProperties.Any();
            }
            return self == to;
        }

        /// <summary>
        /// Type 을 단순하게 변경합니다.
        /// </summary>
        private static bool IsSimpleType(this Type type)
        {
            return
               type.IsValueType ||
               type.IsPrimitive ||
               new[] {typeof(String),typeof(Decimal),typeof(DateTime),typeof(DateTimeOffset),typeof(TimeSpan),typeof(Guid)}.Contains(type) ||
               (Convert.GetTypeCode(type) != TypeCode.Object);
        }

        /// <summary>
        /// MemberType 에 따라 Type 을 반환합니다.
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        private static Type GetUnderlyingType(this MemberInfo member)
        {
            switch (member.MemberType)
            {
                case MemberTypes.Event:
                    return ((EventInfo)member).EventHandlerType;
                case MemberTypes.Field:
                    return ((FieldInfo)member).FieldType;
                case MemberTypes.Method:
                    return ((MethodInfo)member).ReturnType;
                case MemberTypes.Property:
                    return ((PropertyInfo)member).PropertyType;
                default:
                    throw new ArgumentException
                    (
                       "Input MemberInfo must be if type EventInfo, FieldInfo, MethodInfo, or PropertyInfo"
                    );
            }
        }
    }

 

사용은 T class 가 있을때 AT, BT 를 비교한다고 할때

bool isEqual = AT.PropertiesEqual<T>(BT);

728x90
그리드형