[C#/LINQ] Expression 클래스 : 지정 타입으로 변환하기
■ Expression 클래스를 사용해 지정 타입으로 변환하는 방법을 보여준다. ▶ 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 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 |
using System; using System.Collections.Generic; using System.Linq.Expressions; namespace TestProject { /// <summary> /// 타입 헬퍼 /// </summary> public static class TypeHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 캐스트 캐시 딕셔너리 /// </summary> private static readonly Dictionary<Tuple<Type, Type>, Func<object, object>> _castCacheDictionary = new Dictionary<Tuple<Type, Type>, Func<object, object>>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 타입 변경하기 - ChangeType(sourceObject) /// <summary> /// 타입 변경하기 /// </summary> /// <typeparam name="TTarget">타겟 타입</typeparam> /// <param name="sourceObject">소스 객체</param> /// <returns>타입 변경 객체</returns> public static TTarget ChangeType<TTarget>(object sourceObject) { return (TTarget)GetCastFunction(sourceObject.GetType(), typeof(TTarget)).Invoke(sourceObject); } #endregion //////////////////////////////////////////////////////////////////////////////// Private #region 캐스트 함수 생성하기 - CreateCastFunction(sourceType, targetType) /// <summary> /// 캐스트 함수 생성하기 /// </summary> /// <param name="sourceType">소스 타입</param> /// <param name="targetType">타겟 타입</param> /// <returns>캐스트 함수</returns> private static Func<object, object> CreateCastFunction(Type sourceType, Type targetType) { ParameterExpression parameterExpression = Expression.Parameter(typeof(object)); return Expression.Lambda<Func<object, object>> ( Expression.Convert ( Expression.ConvertChecked(Expression.Convert(parameterExpression, sourceType), targetType), typeof(object) ), parameterExpression ).Compile(); } #endregion #region 캐스트 함수 구하기 - GetCastFunction(sourceType, targetType) /// <summary> /// 캐스트 함수 구하기 /// </summary> /// <param name="sourceType">소스 타겟</param> /// <param name="targetType">타겟 타입</param> /// <returns>캐스트 함수</returns> private static Func<object, object> GetCastFunction(Type sourceType, Type targetType) { lock(_castCacheDictionary) { Tuple<Type, Type> keyTuple = new Tuple<Type, Type>(sourceType, targetType); Func<object, object> castFunction; if(!_castCacheDictionary.TryGetValue(keyTuple, out castFunction)) { castFunction = CreateCastFunction(sourceType, targetType); _castCacheDictionary.Add(keyTuple, castFunction); } return castFunction; } } #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 |
using System; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { double sourceValue = 100d; int targetValue = TypeHelper.ChangeType<int>(sourceValue); Console.WriteLine($"소스 값 : {sourceValue.GetType()}, {sourceValue}"); Console.WriteLine($"타겟 값 : {targetValue.GetType()}, {targetValue}"); } #endregion } } |
TestProject.zip