■ 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 클래스 : 자식 타입 여부 구하기 (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 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 124 |
#region 자식 타입 여부 구하기 - IsChildType(childType, parentType) /// <summary> /// 자식 타입 여부 구하기 /// </summary> /// <param name="childType">자식 타입</param> /// <param name="parentType">부모 타입</param> /// <returns>자식 타엽 여부</returns> public bool IsChildType(Type childType, Type parentType) { if(childType == parentType) { return false; } if(childType.IsSubclassOf(parentType)) { return true; } Type[] genericArgumentTypeArray = parentType.GetGenericArguments(); bool isParameterLessGeneric = ! ( genericArgumentTypeArray != null && genericArgumentTypeArray.Length > 0 && ((genericArgumentTypeArray[0].Attributes & TypeAttributes.BeforeFieldInit) == TypeAttributes.BeforeFieldInit) ); while(childType != null && childType != typeof(object)) { Type fullType = GetFullTypeDefinition(childType); if ( parentType == fullType || (isParameterLessGeneric && fullType.GetInterfaces().Select(i => GetFullTypeDefinition(i)).Contains(GetFullTypeDefinition(parentType))) ) { return true; } else if(!isParameterLessGeneric) { if(GetFullTypeDefinition(parentType) == fullType && !fullType.IsInterface) { if(VerifyGenericArguments(GetFullTypeDefinition(parentType), fullType)) { if(VerifyGenericArguments(parentType, childType)) { return true; } } } else { foreach(Type interfaceType in childType.GetInterfaces().Where(i => GetFullTypeDefinition(parentType) == GetFullTypeDefinition(i))) { if(VerifyGenericArguments(parentType, interfaceType)) { return true; } } } } childType = childType.BaseType; } return false; } #endregion #region 완전한 타입 정의 구하기 - GetFullTypeDefinition(sourceType) /// <summary> /// 완전한 타입 정의 구하기 /// </summary> /// <param name="sourceType">소스 타입</param> /// <returns>완전한 타입</returns> private Type GetFullTypeDefinition(Type sourceType) { return sourceType.IsGenericType ? sourceType.GetGenericTypeDefinition() : sourceType; } #endregion #region 제네릭 인자 확인하기 - VerifyGenericArguments(parentType, childType) /// <summary> /// 제네릭 인자 확인하기 /// </summary> /// <param name="parentType">부모 타입</param> /// <param name="childType">자식 타입</param> /// <returns>제네릭 인자 확인 결과</returns> private bool VerifyGenericArguments(Type parentType, Type childType) { Type[] childArgumentTypeArray = childType.GetGenericArguments(); Type[] parentArgumentTypeArray = parentType.GetGenericArguments(); if(childArgumentTypeArray.Length == parentArgumentTypeArray.Length) { for(int i = 0; i < childArgumentTypeArray.Length; i++) { if ( childArgumentTypeArray[i].Assembly != parentArgumentTypeArray[i].Assembly || childArgumentTypeArray[i].Name != parentArgumentTypeArray[i].Name || childArgumentTypeArray[i].Namespace != parentArgumentTypeArray[i].Namespace ) { if(!childArgumentTypeArray[i].IsSubclassOf(parentArgumentTypeArray[i])) { return false; } } } } return true; } #endregion |