정보창, 에디트 구조 작성

This commit is contained in:
logonkhi
2025-06-19 19:24:30 +09:00
parent 21020f590f
commit a6ac3e6b78
1486 changed files with 697081 additions and 1507 deletions

View File

@@ -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;
}
}
}