728x90
반응형
728x170
▶ Type 클래스 : 자식 타입 여부 구하기 예제
/// <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)));
728x90
▶ Type 클래스 : 자식 타입 여부 구하기
#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
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON/.NET6] StackFrame 클래스 : GetFileLineNumber 메소드를 사용해 예외 발생 소스 코드 줄 번호 구하기 (0) | 2022.06.21 |
---|---|
[C#/COMMON/.NET6] 포맷 문자열에서 중괄호를 이스케이프 처리하기 (0) | 2022.06.21 |
[C#/COMMON/.NET6] MIME 타입 딕셔너리 구하기 (.NET 프레임워크 MimeMappings 클래스 소스 코드 기준) (0) | 2022.06.21 |
[C#/COMMON] MimeMapping 클래스 : GetMimeMapping 정적 메소드를 사용해 파일명에서 MIME 타입 구하기 (0) | 2022.06.21 |
[C#/COMMON/.NET6] MemoryStream 클래스 : Write 메소드를 사용해 바이트 배열 병합하기 (0) | 2022.06.21 |
[C#/COMMON/.NET6] Type 클래스 : 자식 타입 여부 구하기 (0) | 2022.06.20 |
[C#/COMMON/.NET6] Type 클래스 : 자식 타입 여부 구하기 (0) | 2022.06.20 |
[C#/COMMON/.NET6] 첫번째 문자가 대문자 문자열 구하기 (0) | 2022.06.20 |
[C#/COMMON/.NET6] 첫번째 문자가 대문자 문자열 구하기 (0) | 2022.06.20 |
[C#/COMMON/.NET6] TextInfo 클래스 : ToTitleCase 메소드를 사용해 단어 첫번째 문자가 대문자 문자열 구하기 (0) | 2022.06.20 |
댓글을 달아 주세요