Programing

변수 유형을 매개 변수로 사용하는 C #의 제네릭

crosscheck 2020. 7. 17. 19:18
반응형

변수 유형을 매개 변수로 사용하는 C #의 제네릭


이 질문에는 이미 답변이 있습니다.

일반적인 방법이 있습니다

bool DoesEntityExist<T>(Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

다음과 같은 방법으로 방법을 사용하는 방법 :

Type t = entity.GetType();
DoesEntityExist<t>(entityGuid, transaction);

다음과 같은 컴파일 오류가 계속 발생합니다.

유형 또는 네임 스페이스 이름 't'을 (를) 찾을 수 없습니다 (사용 지시문 또는 어셈블리 참조가 누락 되었습니까?)

DoesEntityExist<MyType>(entityGuid, transaction);

완벽하게 작동하지만 매번 별도의 유형 이름으로 메소드를 호출하기 위해 if 지시문을 사용하고 싶지 않습니다.


제네릭에 대한 요점은 컴파일 타임 유형 안전성 을 제공 하는 것입니다. 즉, 컴파일 타임에 유형을 알아야합니다.

당신은 할 수 있습니다 만 실행 시간에 알려진 유형의 일반적인 메소드를 호출,하지만 당신은 사용 반사에 있습니다 :

// For non-public methods, you'll need to specify binding flags too
MethodInfo method = GetType().GetMethod("DoesEntityExist")
                             .MakeGenericMethod(new Type[] { t });
method.Invoke(this, new object[] { entityGuid, transaction });

Ick.

대신 호출 메소드를 제네릭으로 만들고 유형 매개 변수로 유형 매개 변수를 전달하여 결정을 스택보다 한 수준 높입니다.

당신이하고있는 일에 대해 더 많은 정보를 제공 할 수 있다면 도움이 될 것입니다. 때때로 위와 같이 리플렉션을 사용해야 할 수도 있지만, 올바른 포인트를 선택하면 한 번만 수행하면되고 그 포인트 아래의 모든 것이 일반적인 방식으로 type 매개 변수를 사용하도록 할 수 있습니다.


이 문제를 해결하는 한 가지 방법은 암시 적 캐스팅을 사용하는 것입니다.

bool DoesEntityExist<T>(T entity, Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

그렇게 부르는 것 :

DoesEntityExist(entity, entityGuid, transaction);

한 단계 더 나아가서 확장 메소드로 변환 할 수 있습니다 (정적 클래스에서 선언해야 함).

static bool DoesEntityExist<T>(this T entity, Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

그렇게 부르기 :

entity.DoesEntityExist(entityGuid, transaction);

귀하의 질문을 올바르게 이해하고 있는지 확실하지 않지만 다음과 같이 코드를 작성할 수 있습니다.

bool DoesEntityExist<T>(T instance, ....)

다음과 같은 방법으로 메소드를 호출 할 수 있습니다.

DoesEntityExist(myTypeInstance, ...)

이렇게하면 명시 적으로 유형을 작성할 필요가 없으며 프레임 워크는 인스턴스에서 자동으로 유형을 인수합니다.


설명 된 방식으로 사용할 수 없습니다. 제네릭 형식에 대한 요점은 "코딩 시간"에서 알 수 없지만 컴파일러는 컴파일시 해당 유형을 확인할 수 있어야한다는 것입니다. 왜? 후드 아래에서 컴파일러는 "개방 된"제네릭 형식의 각각의 다른 사용법에 대해 새로운 유형 (종종 폐쇄 형 형식이라고도 함)을 생성합니다.

다시 말해 컴파일 후

DoesEntityExist<int>

다른 유형입니다

DoesEntityExist<string>

이것이 컴파일러가 컴파일 타임 타입 안전을 보장 할 수있는 방법입니다.

설명하는 시나리오의 경우 유형을 런타임에 검사 할 수있는 인수로 전달해야합니다.

다른 답변에서 언급했듯이 다른 옵션은 리플렉션을 사용하여 열린 유형에서 닫힌 유형을 만드는 것입니다.하지만 내가 말한 극단적 인 틈새 시나리오 이외의 다른 경우에 권장됩니다.

참고 URL : https://stackoverflow.com/questions/2107845/generics-in-c-using-type-of-a-variable-as-parameter

반응형