정보창, 에디트 구조 작성
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace UVC.Extention
|
||||
@@ -153,5 +156,159 @@ namespace UVC.Extention
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 두 사전의 키와 값을 비교하여 두 사전이 같은지 확인합니다.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">사전의 키 유형입니다.</typeparam>
|
||||
/// <typeparam name="TValue">사전의 값 유형입니다.</typeparam>
|
||||
/// <param name="dic">비교할 첫 번째 사전입니다.</param>
|
||||
/// <param name="other">비교할 두 번째 사전입니다.</param>
|
||||
/// <paramref name="dic"/>의 모든 키가 <paramref name="other"/>에 존재하고 해당 값이 같으면 <see langword="true"/>를 반환합니다.
|
||||
/// 그렇지 않으면 <see langword="false"/>를 반환합니다.</returns>
|
||||
public static bool IsSame<TKey, TValue>(this IDictionary<TKey, TValue> dic, IDictionary<TKey, TValue> other)
|
||||
{
|
||||
return !dic.Keys.Any(key => !object.Equals(dic[key], other[key]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 두 사전을 비교하여 두 번째 사전의 키와 값을 포함하는 새 사전을 반환합니다.
|
||||
/// 두 사전의 값이 첫 번째 사전의 값과 다릅니다.
|
||||
/// </summary>
|
||||
/// <remarks>이 메서드는 <see
|
||||
/// cref="object.Equals(object, object)"/>를 사용하여 얕은 값 비교를 수행합니다. 키가 <paramref name="oldDict"/>에는 있지만 <paramref
|
||||
/// name="newDict"/>에는 없는 경우, 또는 그 반대의 경우, 해당 키는 무시됩니다.</remarks>
|
||||
/// <typeparam name="TKey">사전에 있는 키의 타입입니다.</typeparam>
|
||||
/// <typeparam name="TValue">사전에 있는 값의 타입입니다.</typeparam>
|
||||
/// <param name="oldDict">비교할 원본 사전입니다.</param>
|
||||
/// <param name="newDict">비교할 업데이트된 사전입니다.</param>
|
||||
/// <returns> <paramref name="newDict"/>의 키가 포함된 사전입니다. 해당 키의 값이 <paramref name="oldDict"/>의 해당 값과 다른 경우입니다.
|
||||
/// 반환된 사전의 값은 <paramref name="newDict"/>에서 가져옵니다.</returns>
|
||||
public static IDictionary<TKey, TValue> Differences<TKey, TValue>(this IDictionary<TKey, TValue> oldDict, IDictionary<TKey, TValue> newDict)
|
||||
{
|
||||
var result = new Dictionary<TKey, TValue>();
|
||||
foreach (var key in oldDict.Keys)
|
||||
{
|
||||
TValue oldValue = oldDict[key];
|
||||
TValue newValue = newDict[key];
|
||||
|
||||
if (!object.Equals(oldValue, newValue))
|
||||
{
|
||||
result.Add(key, newValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 두 사전을 비교하여 두 번째 사전의 키와 값을 포함하는 새 사전을 반환합니다.
|
||||
/// 두 사전의 값이 첫 번째 사전의 값과 다릅니다.
|
||||
/// </summary>
|
||||
/// <remarks>이 메서드는 심층 비교를 사용하여 값이 다른지 확인합니다. 비교
|
||||
/// 로직은 <c>DeepEquals</c> 메서드로 정의됩니다. <paramref name="dict1"/>에는 있지만
|
||||
/// <paramref name="dict2"/>에는 없는 키는 결과에 포함되지 않습니다.</remarks>
|
||||
/// <typeparam name="TKey">사전에 있는 키의 타입입니다.</typeparam>
|
||||
/// <typeparam name="TValue">사전에 있는 값의 타입입니다.</typeparam>
|
||||
/// <param name="dict1">비교할 첫 번째 사전입니다.</param>
|
||||
/// <param name="dict2">비교할 두 번째 사전입니다.</param>
|
||||
/// <returns><paramref name="dict2"/>의 키와 값을 포함하는 사전으로, 값이 <paramref name="dict1"/>의 값과 다른 경우
|
||||
/// <paramref name="dict1"/>에 키가 있지만 값이 같지 않으면
|
||||
/// <paramref name="dict2"/>의 키와 해당 값이 포함됩니다.</returns>
|
||||
public static IDictionary<TKey, TValue> DeepDifferences<TKey, TValue>(this IDictionary<TKey, TValue> dict1, IDictionary<TKey, TValue> dict2)
|
||||
{
|
||||
var result = new Dictionary<TKey, TValue>();
|
||||
foreach (var key in dict1.Keys)
|
||||
{
|
||||
TValue val1 = dict1[key];
|
||||
TValue val2 = dict2[key];
|
||||
if (!DeepEquals(val1, val2))
|
||||
{
|
||||
result.Add(key, val2);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 두 객체의 값, 속성 및 중첩 구조를 비교하여 두 객체가 깊이 동일한지 여부를 확인합니다.
|
||||
///
|
||||
// </summary>
|
||||
/// <remarks>이 메서드는 제공된 객체와 중첩 구조를 재귀적으로 비교합니다.
|
||||
/// 기본 유형, 문자열, 소수, 컬렉션(예: 배열,리스트), 사전 및 복합 객체의 비교를 지원합니다.
|
||||
/// 컬렉션의 경우, 이 메서드는 요소를 순서대로 비교합니다.
|
||||
/// 사전의 경우, 키와 연관된 값을 비교합니다. 객체의 유형이 다르거나 일치하지 않는 구조를 가진 경우,
|
||||
/// 이 메서드는 <see langword="false"/>를 반환합니다.</remarks>
|
||||
/// <param name="obj1">비교할 첫 번째 객체입니다. null일 수 있습니다.</param>
|
||||
/// <param name="obj2">비교할 두 번째 객체입니다. null일 수 있습니다.</param>
|
||||
/// 객체가 깊이 동일하면 <returns><see langword="true"/>를 반환하고, 그렇지 않으면 <see langword="false"/>를 반환합니다. 깊이 동일성
|
||||
///에는 기본 값, 문자열, 컬렉션, 사전 및 복합 객체의 공개 속성 비교가 포함됩니다.
|
||||
///</returns>
|
||||
private static bool DeepEquals(object obj1, object obj2)
|
||||
{
|
||||
if (ReferenceEquals(obj1, obj2))
|
||||
return true;
|
||||
|
||||
if (obj1 == null || obj2 == null)
|
||||
return false;
|
||||
|
||||
if (obj1.Equals(obj2))
|
||||
return true;
|
||||
|
||||
var type1 = obj1.GetType();
|
||||
var type2 = obj2.GetType();
|
||||
|
||||
if (type1 != type2)
|
||||
return false;
|
||||
|
||||
// String or primitive
|
||||
if (type1.IsPrimitive || obj1 is string || obj1 is decimal)
|
||||
return obj1.Equals(obj2);
|
||||
|
||||
// List or Array
|
||||
if (obj1 is IEnumerable enumerable1 && obj2 is IEnumerable enumerable2)
|
||||
{
|
||||
var list1 = enumerable1.Cast<object>().ToList();
|
||||
var list2 = enumerable2.Cast<object>().ToList();
|
||||
|
||||
if (list1.Count != list2.Count)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < list1.Count; i++)
|
||||
{
|
||||
if (!DeepEquals(list1[i], list2[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Dictionary
|
||||
if (obj1 is IDictionary dict1 && obj2 is IDictionary dict2)
|
||||
{
|
||||
if (dict1.Count != dict2.Count)
|
||||
return false;
|
||||
|
||||
foreach (var key in dict1.Keys)
|
||||
{
|
||||
if (!dict2.Contains(key)) return false;
|
||||
if (!DeepEquals(dict1[key], dict2[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Complex object
|
||||
var props = type1.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (var prop in props)
|
||||
{
|
||||
var val1 = prop.GetValue(obj1);
|
||||
var val2 = prop.GetValue(obj2);
|
||||
if (!DeepEquals(val1, val2))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user