첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
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)
{
    parentType = ResolveGenericTypeDefinition(parentType);

    Type currenType = childType.IsGenericType ? childType.GetGenericTypeDefinition() : childType;

    while(currenType != typeof(object))
    {
        if(parentType == currenType || HasAnyInterfaceType(parentType, currenType))
        {
            return true;
        }

        currenType = currenType.BaseType != null && currenType.BaseType.IsGenericType
            ? currenType.BaseType.GetGenericTypeDefinition()
            : currenType.BaseType;

        if(currenType == null)
        {
            return false;
        }
    }

    return false;
}

#endregion

#region 제네릭 타입 정의 확인하기 - ResolveGenericTypeDefinition(parentType)

/// <summary>
/// 제네릭 타입 정의 확인하기
/// </summary>
/// <param name="parentType">부모 타입</param>
/// <returns>제네릭 타입 정의 확인 타입</returns>
private Type ResolveGenericTypeDefinition(Type parentType)
{
    bool shouldUseGenericType = true;

    if(parentType.IsGenericType && parentType.GetGenericTypeDefinition() != parentType)
    {
        shouldUseGenericType = false;
    }

    if(parentType.IsGenericType && shouldUseGenericType)
    {
        parentType = parentType.GetGenericTypeDefinition();
    }

    return parentType;
}

#endregion
#region 인터페이스 타입 소유 여부 구하기 - HasAnyInterfaceType(parentType, childType)

/// <summary>
/// 인터페이스 타입 소유 여부 구하기
/// </summary>
/// <param name="parentType">부모 타입</param>
/// <param name="childType">자식 타입</param>
/// <returns>인터페이스 타입 소유 여부</returns>
private bool HasAnyInterfaceType(Type parentType, Type childType)
{
    return childType.GetInterfaces()
        .Any
        (
            interfaceType =>
            {
                Type type = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;

                return type == parentType;
            }
        );
}

#endregion
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요