[C#/WINUI3/.NET8] ListView 엘리먼트 : DisplayMemberPath 속성을 사용해 항목 표시하기
■ ListView 엘리먼트의 DisplayMemberPath 속성을 사용해 항목을 표시하는 방법을 보여준다. ※ ItemTemplate 및 DisplayMemberPath를 동시에 사용할 수 없다. 두 속성을 모두 설정한
■ ListView 엘리먼트의 DisplayMemberPath 속성을 사용해 항목을 표시하는 방법을 보여준다. ※ ItemTemplate 및 DisplayMemberPath를 동시에 사용할 수 없다. 두 속성을 모두 설정한
■ RuntimeReflectionExtensions 클래스의 GetRuntimeProperties 확장 메소드를 사용해 Colors 클래스의 색상 정적 속성들에서 색상 딕셔너리를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
using System.Collections.Generic; using System.Reflection; using Windows.UI; using Microsoft.UI; IEnumerable<PropertyInfo> propertyInfoEnumerable = typeof(Colors).GetRuntimeProperties(); List<Color> colorList = new List<Color>(); foreach(PropertyInfo propertyInfo in propertyInfoEnumerable) { if(!propertyInfo.GetMethod.IsStatic) { continue; } if(propertyInfo.PropertyType != typeof(Color)) { continue; } Color color = (Color)propertyInfo.GetValue(null); colorList.Add(color); } |
■ RuntimeReflectionExtensions 클래스의 GetRuntimeProperties 확장 메소드를 사용해 특정 타입의 속성 열거 가능형을 구하는 방법을 보여준다. ▶ 예제 코드 1 (C#)
1 2 3 4 5 6 7 8 |
using System.Collections.Generic; using System.Reflection; using Microsoft.UI; IEnumerable<PropertyInfo> propertyInfoEnumerable = typeof(Colors).GetRuntimeProperties(); |
▶
■ 규칙 엔진을 만드는 기본적인 방법을 보여준다. ▶ User.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
namespace TestProject; /// <summary> /// 사용자 /// </summary> public class User { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 성명 - Name /// <summary> /// 성명 /// </summary> public string Name { get; set; } #endregion #region 나이 - Age /// <summary> /// 나이 /// </summary> public int Age { get; set; } #endregion } |
▶ Operator.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
using System.Reflection; namespace TestProject; /// <summary> /// 연산자 /// </summary> public static class Operator { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 함수 딕셔너리 /// </summary> private static Dictionary<string, Func<object, object, bool>> _functionDictionary; /// <summary> /// 속성 정보 딕셔너리 /// </summary> private static Dictionary<string, PropertyInfo> _propertyInfoDictionary; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static #region 생성자 - Operator() /// <summary> /// 생성자 /// </summary> static Operator() { _functionDictionary = new Dictionary<string, Func<object, object, bool>>(); _functionDictionary["greater_than"] = new Func<object, object, bool>(ProcessOperatorGreaterThan); _functionDictionary["equal" ] = new Func<object, object, bool>(ProcessOperatorEqual); _propertyInfoDictionary = typeof(User).GetProperties().ToDictionary(propInfo => propInfo.Name); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 적용하기 - Apply(user, opertatorName, propertyName, targetValue) /// <summary> /// 적용하기 /// </summary> /// <param name="user">사용자</param> /// <param name="opertatorName">연산자명</param> /// <param name="propertyName">속성명</param> /// <param name="targetValue">타겟 값</param> /// <returns>적용 결과</returns> public static bool Apply(User user, string opertatorName, string propertyName, object targetValue) { return _functionDictionary[opertatorName](GetPropertyValue(user, propertyName), targetValue); } #endregion //////////////////////////////////////////////////////////////////////////////// Private #region 속성 값 구하기 - GetPropertyValue(user, propertyName) /// <summary> /// 속성 값 구하기 /// </summary> /// <param name="user">사용자</param> /// <param name="propertyName">속성명</param> /// <returns>속성 값</returns> private static object GetPropertyValue(User user, string propertyName) { PropertyInfo propertyInfo = _propertyInfoDictionary[propertyName]; return propertyInfo.GetGetMethod(false).Invoke(user, null); } #endregion #region 연산자 >> 처리하기 - ProcessOperatorGreaterThan(source1, source2) /// <summary> /// 연산자 >> 처리하기 /// </summary> /// <param name="source1">소스 객체 1</param> /// <param name="source2">소스 객체 2</param> /// <returns>처리 결과</returns> private static bool ProcessOperatorGreaterThan(object source1, object source2) { if(source1 == null || source2 == null || source1.GetType() != source2.GetType() || !(source1 is IComparable)) { return false; } return (source1 as IComparable).CompareTo(source2) > 0; } #endregion #region 연산자 == 처리하기 - ProcessOperatorEqual(source1, source2) /// <summary> /// 연산자 == 처리하기 /// </summary> /// <param name="source1">소스 객체 1</param> /// <param name="source2">소스 객체 2</param> /// <returns>처리 결과</returns> private static bool ProcessOperatorEqual(object source1, object source2) { return source1 == source2; } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { User user = new User() { Age = 16, Name = "John" }; Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 15)); Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 17)); Console.WriteLine(Operator.Apply(user, "equal", "Name", "John")); Console.WriteLine(Operator.Apply(user, "equal", "Name", "Bob" )); } #endregion } |
TestProject.zip
■ Control 클래스를 사용해 컨트롤 이벤트를 제거하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.ComponentModel; using System.Reflection; using System.Windows.Forms; #region 이벤트 제거하기 - RemoveEvent(targetControl, eventName) /// <summary> /// 이벤트 제거하기 /// </summary> /// <param name="targetControl">타겟 컨트롤</param> /// <param name="eventName">이벤트명</param> public void RemoveEvent(Control targetControl, string eventName) { FieldInfo fieldInfo = typeof(Control).GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic); PropertyInfo propertyInfo = targetControl.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); object fieldValue = fieldInfo.GetValue(targetControl); EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(targetControl, null); eventHandlerList.RemoveHandler(fieldValue, eventHandlerList[fieldValue]); } #endregion |
■ 참조 어셈블리를 로드하는 방법을 보여준다. ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
using System.Reflection; namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 참조 어셈블리 로드하기 - LoadReferencedAssembly(assembly, assemblyLevel) /// <summary> /// 참조 어셈블리 로드하기 /// </summary> /// <param name="assembly">어셈블리</param> /// <param name="assemblyLevel">어셈블리 레벨</param> private static void LoadReferencedAssembly(Assembly assembly, int assemblyLevel = 0) { Console.WriteLine($"{" ".PadRight(assemblyLevel * 4)}{assembly.GetName().Name}"); foreach(AssemblyName name in assembly.GetReferencedAssemblies()) { if(!AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName == name.FullName)) { LoadReferencedAssembly(Assembly.Load(name), assemblyLevel + 1); } } } #endregion #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { LoadReferencedAssembly(assembly); } } #endregion } |
TestProject.zip
■ dynamic 타입 객체의 속성 값을 동적으로 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 |
dynamic instance = new { value1 = "some", value2 = "random", value3 = "value" }; object value = instance.GetType().GetProperty("value2").GetValue(instance, null); Console.WriteLine(value); |
■ Expression<T> 클래스를 사용해 객체 속성 정보를 구하는 방법을 보여준다. ▶ Product.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
namespace TestProject; /// <summary> /// 제품 /// </summary> public class Product { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 제품 코드 - ProductCode /// <summary> /// 제품 코드 /// </summary> public string ProductCode { get; set; } #endregion #region 명칭 - Name /// <summary> /// 명칭 /// </summary> public string Name { get; set; } #endregion #region 가격 - Price /// <summary> /// 가격 /// </summary> public decimal Price { get; set; } #endregion } |
▶ PropertyHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System.Linq.Expressions; using System.Reflection; namespace TestProject; /// <summary> /// 속성 헬퍼 /// </summary> /// <typeparam name="TSource">소스 타입</typeparam> public static class PropertyHelper<TSource> { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 속성 정보 구하기 - GetPropertyInfo<TProperty>(selector) /// <summary> /// 속성 정보 구하기 /// </summary> /// <typeparam name="TProperty">속성 타입</typeparam> /// <param name="selector">셀렉터</param> /// <returns>속성 정보</returns> public static PropertyInfo GetPropertyInfo<TProperty>(Expression<Func<TSource, TProperty>> selector) { Expression body = selector; if(body is LambdaExpression) { body = ((LambdaExpression)body).Body; } switch(body.NodeType) { case ExpressionType.MemberAccess : return (PropertyInfo)((MemberExpression)body).Member; default : throw new InvalidOperationException(); } } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
using System.Reflection; namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Product product = new Product { ProductCode = "0001", Name = "제품A", Price = 25_000 }; PropertyInfo propertyInfo = PropertyHelper<Product>.GetPropertyInfo(x => x.Name); Console.WriteLine(propertyInfo.GetValue(product)); } #endregion } |
TestProject.zip
■ Expression<T> 클래스를 사용해 객체 속성에 설정된 어트리뷰트를 구하는 방법을 보여준다. ▶ CustomAttribute.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
namespace TestProject; /// <summary> /// 커스텀 어트리뷰트 /// </summary> public class CustomAttribute : Attribute { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 텍스트 - Text /// <summary> /// 텍스트 /// </summary> public string Text { get; protected set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - CustomAttribute(text) /// <summary> /// 생성자 /// </summary> /// <param name="text">텍스트</param> public CustomAttribute(string text) { Text = text; } #endregion } |
▶ Product.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
namespace TestProject; /// <summary> /// 제품 /// </summary> public class Product { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 제품 코드 - ProductCode /// <summary> /// 제품 코드 /// </summary> public string ProductCode { get; set; } #endregion #region 명칭 - Name /// <summary> /// 명칭 /// </summary> [Custom("테스트")] public string Name { get; set; } #endregion #region 가격 - Price /// <summary> /// 가격 /// </summary> public decimal Price { get; set; } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
using System.Linq.Expressions; using System.Reflection; namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Type sourceType = typeof(Product); PropertyInfo propertyInfo = sourceType.GetProperty("Name"); Expression<Func<Product, string>> expression = p => p.Name; MemberExpression memberExpression = expression.Body as MemberExpression; object[] customAttributeArray = memberExpression.Member.GetCustomAttributes(typeof(CustomAttribute), false); if(customAttributeArray.Length > 0) { Console.WriteLine((customAttributeArray[0] as CustomAttribute).Text); } } #endregion } |
TestProject.zip
■ PropertyInfo 클래스의 GetCustomAttributes 메소드를 사용해 객체 속성에 설정된 어트리뷰트를 구하는 방법을 보여준다. ▶ CustomAttribute.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
namespace TestProject; /// <summary> /// 커스텀 어트리뷰트 /// </summary> public class CustomAttribute : Attribute { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 텍스트 - Text /// <summary> /// 텍스트 /// </summary> public string Text { get; protected set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - CustomAttribute(text) /// <summary> /// 생성자 /// </summary> /// <param name="text">텍스트</param> public CustomAttribute(string text) { Text = text; } #endregion } |
▶ Product.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
namespace TestProject; /// <summary> /// 제품 /// </summary> public class Product { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 제품 코드 - ProductCode /// <summary> /// 제품 코드 /// </summary> public string ProductCode { get; set; } #endregion #region 명칭 - Name /// <summary> /// 명칭 /// </summary> [Custom("테스트")] public string Name { get; set; } #endregion #region 가격 - Price /// <summary> /// 가격 /// </summary> public decimal Price { get; set; } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System.Reflection; namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Type sourceType = typeof(Product); PropertyInfo propertyInfo = sourceType.GetProperty("Name"); CustomAttribute[] customAttributeArray = (CustomAttribute[])propertyInfo.GetCustomAttributes(typeof(CustomAttribute), false); if(customAttributeArray.Length > 0) { Console.WriteLine(customAttributeArray[0].Text); } } #endregion } |
■ Attribute 클래스의 IsDefined 정적 메소드를 사용해 객체 속성의 어트리뷰트 설정 여부를 구하는 방법을 보여준다. ▶ CustomAttribute.cs
1 2 3 4 5 6 7 8 9 10 |
namespace TestProject; /// <summary> /// 커스텀 어트리뷰트 /// </summary> public class CustomAttribute : Attribute { } |
▶ Product.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
namespace TestProject; /// <summary> /// 제품 /// </summary> public class Product { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 제품 코드 - ProductCode /// <summary> /// 제품 코드 /// </summary> public string ProductCode { get; set; } #endregion #region 명칭 - Name /// <summary> /// 명칭 /// </summary> [Custom] public string Name { get; set; } #endregion #region 가격 - Price /// <summary> /// 가격 /// </summary> public decimal Price { get; set; } #endregion } |
▶
■ Activator 클래스의 CreateInstance 정적 메소드를 사용해 객체 디폴트 값을 구하는 방법을 보여준다. ▶ TypeHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using System.Collections.Concurrent; namespace TestProject; /// <summary> /// 타입 헬퍼 /// </summary> public static class TypeHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 타입 딕셔너리 /// </summary> private static ConcurrentDictionary<Type, object> _typeDictionary = new ConcurrentDictionary<Type, object>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 객체 디폴트 값 구하기 - GetObjectDefaultValue(sourceType) /// <summary> /// 객체 디폴트 값 구하기 /// </summary> /// <param name="sourceType">소스 타입</param> /// <returns>객체 디폴트 값</returns> public static object GetObjectDefaultValue(Type sourceType) { return sourceType.IsValueType ? _typeDictionary.GetOrAdd(sourceType, Activator.CreateInstance) : null; } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.WriteLine(TypeHelper.GetObjectDefaultValue(typeof(int ))); Console.WriteLine(TypeHelper.GetObjectDefaultValue(typeof(string ))); Console.WriteLine(TypeHelper.GetObjectDefaultValue(typeof(DateTime))); } #endregion } |
TestProject.zip
■ Type 클래스를 사용해 객체의 디폴트 값을 구하는 방법을 보여준다. ▶ Type 클래스 : 객체 디폴트 값 구하기 예제 (C#)
1 2 3 4 5 |
Console.WriteLine($"int : {GetObjectDefaultValue(typeof(int ))}"); Console.WriteLine($"string : {GetObjectDefaultValue(typeof(string ))}"); Console.WriteLine($"DateTime : {GetObjectDefaultValue(typeof(DateTime))}"); |
▶
■ 속성에서 값 할당 가능 여부를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#region 속성 값 할당 가능 여부 구하기 - CanAssignPropertyValue(propertyInfo, value) /// <summary> /// 속성 값 할당 가능 여부 구하기 /// </summary> /// <param name="propertyInfo">속성 정보</param> /// <param name="value">값</param> /// <returns>속성 값 할당 가능 여부</returns> public bool CanAssignPropertyValue(PropertyInfo propertyInfo, object value) { return value == null ? IsNullable(propertyInfo) : propertyInfo.PropertyType.IsInstanceOfType(value); } #endregion #region Nullable 타입 여부 구하기 - IsNullable(type) /// <summary> /// Nullable 타입 여부 구하기 /// </summary> /// <param name="type">타입</param> /// <returns>Nullable 타입 여부</returns> public bool IsNullable(Type type) { return !type.IsValueType || Nullable.GetUnderlyingType(type) != null; } #endregion #region Nullable 타입 여부 구하기 - IsNullable(propertyInfo) /// <summary> /// Nullable 타입 여부 구하기 /// </summary> /// <param name="propertyInfo">속성 정보</param> /// <returns>Nullable 타입 여부</returns> public bool IsNullable(PropertyInfo propertyInfo) { return IsNullable(propertyInfo.PropertyType); } #endregion |
■ Activator 클래스의 CreateInstance 정적 메소드를 사용해 제네릭 객체를 생성하는 방법을 보여준다. ▶ Activator 클래스 : CreateInstance 정적 메소드를 사용해 제네릭 객체
■ Assembly 클래스의 GetExecutingAssembly 정적 메소드를 사용해 실행 어셈블리의 제품 버전을 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 |
using System.Diagnostics; using System.Reflection; string assemblyFilePath = Assembly.GetExecutingAssembly().Location; string productVersion = FileVersionInfo.GetVersionInfo(assemblyFilePath).ProductVersion; |
■ Assembly 클래스의 GetEntryAssembly 정적 메소드를 사용해 진입 어셈블리의 버전을 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 |
string version = Assembly.GetEntryAssembly().GetName().Version.ToString(); |
■ Type 클래스를 사용해 자식 타입 여부를 구하는 방법을 보여준다. ▶ Type 클래스 : 자식 타입 여부 구하기 예제 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/// <summary> /// 테스트 인터페이스 /// </summary> public interface ITest { } /// <summary> /// 테스트 제네릭 인터페이스 /// </summary> /// <typeparam name="T"></typeparam> public interface ITest<T> { } /// <summary> /// 테스트 베이스 /// </summary> public class TestBase { } /// <summary> /// 테스트 /// </summary> public class Test : TestBase, ITest { } /// <summary> /// 자식 테스트 /// </summary> public class ChildTest : Test, ITest<object> { } /// <summary> /// 자식 테스트 제네릭 /// </summary> /// <typeparam name="T"></typeparam> public class ChildTest<T> : Test, ITest<T> { } Console.WriteLine(IsChildType(typeof(Test), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(Test), typeof(ITest))); Console.WriteLine(); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(Test))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(ITest<>))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(ITest))); Console.WriteLine(); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(Test))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(ITest<>))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(ITest))); |
▶
■ Type 클래스를 사용해 자식 타입 여부를 구하는 방법을 보여준다. ▶ Type 클래스 : 자식 타입 여부 구하기 예제 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/// <summary> /// 테스트 인터페이스 /// </summary> public interface ITest { } /// <summary> /// 테스트 제네릭 인터페이스 /// </summary> /// <typeparam name="T"></typeparam> public interface ITest<T> { } /// <summary> /// 테스트 베이스 /// </summary> public class TestBase { } /// <summary> /// 테스트 /// </summary> public class Test : TestBase, ITest { } /// <summary> /// 자식 테스트 /// </summary> public class ChildTest : Test, ITest<object> { } /// <summary> /// 자식 테스트 제네릭 /// </summary> /// <typeparam name="T"></typeparam> public class ChildTest<T> : Test, ITest<T> { } Console.WriteLine(IsChildType(typeof(Test), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(Test), typeof(ITest))); Console.WriteLine(); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(Test))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(ITest<>))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(ChildTest), typeof(ITest))); Console.WriteLine(); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(Test))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(ITest<>))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(TestBase))); Console.WriteLine(IsChildType(typeof(ChildTest<>), typeof(ITest))); |
▶
■ Type 클래스를 사용해 자식 타입 여부를 구하는 방법을 보여준다. ▶ Type 클래스 : 자식 타입 여부 구하기 예제 (C#)
1 2 3 4 |
Console.WriteLine(IsChildType(typeof(HttpClient ), typeof(HttpMessageInvoker))); Console.WriteLine(IsChildType(typeof(HttpRequestMessage), typeof(HttpMessageInvoker))); |
▶
■ IntrospectionExtensions 클래스의 GetTypeInfo 확장 메소드를 사용해 특정 객체의 어셈블리를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Reflection; #region 어셈블리 구하기 - GetAssembly(source) /// <summary> /// 어셈블리 구하기 /// </summary> /// <param name="source">소스 객체</param> /// <returns>어셈블리</returns> public Assembly GetAssembly(object source) { Assembly assembly = source.GetType().GetTypeInfo().Assembly; return assembly; } #endregion |
■ DynamicMethod 클래스의 Invoke 메소드를 사용해 구조체 크기를 구하는 방법을 보여준다. ▶ StructureHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
using System; using System.Collections.Generic; using System.Reflection.Emit; namespace TestProject { /// <summary> /// 구조체 헬퍼 /// </summary> public static class StructureHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 타입 딕셔너리 /// </summary> private static Dictionary<Type, int> _typeDictionary = new Dictionary<Type, int>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 크기 구하기 - SizeOf(type) /// <summary> /// 크기 구하기 /// </summary> /// <param name="type">타입</param> /// <returns>크기</returns> public static int SizeOf(Type type) { int size; if(_typeDictionary.TryGetValue(type, out size)) { return size; } size = GetSize(type); _typeDictionary.Add(type, size); return size; } #endregion //////////////////////////////////////////////////////////////////////////////// Private #region 크기 - GetSize(type) /// <summary> /// 크기 구하기 /// </summary> /// <param name="type">타입</param> /// <returns>크기</returns> private static int GetSize(Type type) { DynamicMethod dynamicMethod = new DynamicMethod("SizeOfType", typeof(int), new Type[] { }); ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(OpCodes.Sizeof, type); ilGenerator.Emit(OpCodes.Ret); return (int)dynamicMethod.Invoke(null, null); } #endregion } } |
▶ Student.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System; namespace TestProject { /// <summary> /// 학생 /// </summary> public unsafe struct Student { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// ID /// </summary> public int ID; /// <summary> /// 성명 /// </summary> public fixed char Name[20]; /// <summary> /// 생성 시간 /// </summary> public DateTime CreateTime; #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { int size = StructureHelper.SizeOf(typeof(Student)); Console.WriteLine($"Student 구조체 크기 : {size}"); } #endregion } } |
TestProject.zip
■ Assembly 클래스의 GetName 메소드를 사용해 어셈블리 버전을 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using System; using System.Reflection; Assembly assembly = Assembly.GetExecutingAssembly(); Version version = assembly.GetName().Version; Console.WriteLine($"어셈블리 버전 : {version}"); Console.WriteLine($" 메이저 : {version.Major }"); Console.WriteLine($" 마이너 : {version.Minor }"); Console.WriteLine($" 빌드 : {version.Build }"); Console.WriteLine($" 리비전 : {version.Revision}"); |
■ Assembly 클래스의 GetTypes 메소드를 사용해 특정 네임스페이스의 클래스 리스트를 구하는 방법을 보여준다. ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 타입 리스트 구하기 - GetTypeList(assembly, nameSpace) /// <summary> /// 타입 리스트 구하기 /// </summary> /// <param name="assembly">어셈블리</param> /// <param name="nameSpace">네임스페이스</param> /// <returns>타입 리스트</returns> private static List<Type> GetTypeList(Assembly assembly, string nameSpace) { return assembly.GetTypes() .Where(type => string.Equals(type.Namespace, nameSpace, StringComparison.Ordinal)) .ToList(); } #endregion #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { List<Type> list = GetTypeList(Assembly.GetExecutingAssembly(), "TestProject"); foreach(Type type in list) { Console.WriteLine(type.Name); } } #endregion } } |
TestProject.zip
■ Assembly 클래스를 사용해 네임스페이스 리스트를 구하는 방법을 보여준다. ▶ Assembly 클래스 : 네임스페이스 리스트 구하기 예제 (C#)
1 2 3 4 5 6 7 8 9 10 11 |
using System; using System.Collections.Generic; List<string> list = GetNamespaceList(Assembly.GetExecutingAssembly()); foreach(string nameSpace in list) { Console.WriteLine(nameSpace); } |
▶ Assembly 클래스