운영자 AS 및 일반 클래스
-
22-08-2019 - |
문제
나는 글을 쓰고있다 .net on-fly CLR 스크립팅을위한 컴파일러 및 실행 방법을 원합니다.
object Execute()
{
return type.InvokeMember(..);
}
T Execute<T>()
{
return Execute() as T; /* doesn't work:
The type parameter 'T' cannot be used with the 'as' operator because
it does not have a class type constraint nor a 'class' constraint */
// also neither typeof(T) not T.GetType(), so on are possible
return (T) Execute(); // ok
}
그러나 나는 운영자라고 생각합니다 as
결과 유형이 아닌 경우 매우 유용합니다 T
메소드가 반환됩니다 null
, 예외 대신! 할 수 있습니까?
해결책
추가해야합니다
where T : class
방법 선언에, 예를 들어
T Execute<T>() where T : class
{
그건 그렇고, 제안대로 일반 래퍼는 실제로 많은 가치를 더하지 않습니다. 발신자는 다음을 쓸 수 있습니다.
MyClass c = whatever.Execute() as MyClass;
또는 그들이 던지기를 원한다면 실패 :
MyClass c = (MyClass)whatever.Execute();
일반 래퍼 방법은 다음과 같습니다.
MyClass c = whatever.Execute<MyClass>();
세 가지 버전은 모두 다른 순서로 정확히 동일한 세 엔티티를 지정해야하므로 더 간단하거나 더 편리하지는 않지만 일반 버전은 일어나고있는 일을 숨기는 반면 "RAW"버전은 각각이 있을지 여부를 분명히합니다. 던지거나 a null
.
(실제 코드에서 예제가 단순화되면 이것은 귀하와 관련이 없을 수 있습니다).
다른 팁
당신은 사용할 수 없습니다 as
제한이없는 일반 유형의 연산자. 이후 as
연산자는 NULL을 사용하여 유형이 아니 었음을 나타내므로 값 유형에서 사용할 수 없습니다. 사용하려면 obj as T
, T
~ 할 것이다 가지다 참조 유형입니다.
T Execute<T>() where T : class
{
return Execute() as T;
}
이 작은 코드는 ~처럼-예어:
return Execute() is T value ? value : default(T)
C# 7에 도입 된 패턴 일치 기능을 사용합니다. 일반 매개 변수를 참조 유형으로 제한하지 않으려면 사용하십시오.
사용자가 원하는 유형에 캐스팅하기 위해 래퍼 메소드를 추가하는 것 같습니다. 따라서 실행에 오버 헤드 만 추가합니다. 사용자를 위해 글을 쓰십시오
int result = Execute<int>();
크게 다르지 않습니다
int result = (int)Execute();
당신은 사용할 수 있습니다 밖으로 발신자의 범위에서 결과를 변수로 작성하고 부울 깃발을 반환하여 성공했는지 여부를 수정하십시오.
bool Execute<T>(out T result) where T : class
{
result = Execute() as T;
return result != null;
}
execute ()가 값 유형을 반환 할 가능성이 있습니까? 그렇다면 클래스 유형에 대한 Earwicker의 방법과 가치 유형에 대한 또 다른 일반 방법이 필요합니다. 다음과 같이 보일 수 있습니다.
Nullable<T> ExecuteForValueType<T> where T : struct
그 방법의 논리는 말할 것입니다
object rawResult = Execute();
그런 다음 Rawresult 유형을 가져 와서 t에 할당 할 수 있는지 확인해야합니다.
Nullable<T> finalReturnValue = null;
Type theType = rawResult.GetType();
Type tType = typeof(T);
if(tType.IsAssignableFrom(theType))
{
finalReturnValue = tType;
}
return finalReturnValue;
마지막으로 원래의 실행 메시지가 어떤 t가 있는지 (클래스 또는 구조물 유형) 파악하고 적절한 구현을 호출하십시오.
참고 : 이것은 거친 기억에서 나온 것입니다. 나는 약 1 년 전에 이것을했고 아마도 모든 세부 사항을 기억하지 못할 것입니다. 그래도 일반적인 방향으로 당신을 지적하는 것이 도움이되기를 바랍니다.