개발 블로그, 온라인 코드 예제 및 (최근) 책에서도 다음과 같은 코드에 대해 계속 걸림돌이됩니다.
var y = x as T;
y.SomeMethod();
또는 더 나쁜 :
(x as T).SomeMethod();
그건 말이되지 않습니다. x
유형 이 확실하다면 T
직접 캐스트를 사용해야합니다 (T)x
.. 확실하지 않은 경우 일부 작업을 수행하기 전에 사용할 수 as
있지만 확인해야 null
합니다. 위의 코드가하는 것은 (유용한) InvalidCastException
를 (유용하지 않은)로 바꾸는 것 NullReferenceException
입니다.
이것이 as
키워드 의 명백한 남용이라고 생각하는 유일한 사람 입니까? 아니면 내가 명백한 것을 그리워하고 위의 패턴이 실제로 의미가 있습니까?
답변
당신의 이해는 사실입니다. 그것은 나에게 미세 최적화하려고하는 것 같습니다. 유형이 확실하면 일반 캐스트를 사용해야합니다. 더 현명한 예외를 생성하는 것 외에도 빠르게 실패합니다. 유형에 대한 당신의 가정에 대해있는 거 잘못이 경우, 프로그램이 즉시 실패하고 당신은을 위해 장애 것이 아니라 즉시 대기의 원인을 볼 수 있습니다 NullReferenceException
또는 ArgumentNullException
미래에 또는 논리적 오류 언젠가. 일반적으로 어딘가에 검사가 as
뒤 따르지 않는 표현식 null
은 코드 냄새입니다.
반면, 캐스트에 대해 확신이없고 실패 할 것으로 예상 as
되는 경우 try-catch
블록으로 랩핑 된 일반 캐스트 대신 사용해야 합니다 . 또한 as
유형 검사 후 캐스트에 사용하는 것이 좋습니다. 대신에:
if (x is SomeType)
((SomeType)x).SomeMethod();
이는 생성 isinst
명령 에 대한 is
키워드 및 castclass
명령 캐스트 (효과적으로 두 번 캐스트를 수행)를 들어, 당신은 사용해야합니다 :
var v = x as SomeType;
if (v != null)
v.SomeMethod();
isinst
명령 만 생성합니다 . 이전의 방법은 경쟁 조건으로 인해 is
검사가 성공하고 캐스트 라인에서 실패한 후 변수의 유형이 변경 될 수 있으므로 다중 스레드 응용 프로그램에 결함이있을 수 있습니다 . 후자의 방법은이 오류가 발생하지 않습니다.
다음 솔루션은 프로덕션 코드에 사용 하지 않는 것이 좋습니다 . C #에서 이러한 기본 구성을 정말로 싫어한다면 VB 또는 다른 언어로 전환하는 것을 고려할 수 있습니다.
캐스트 구문을 필사적으로 싫어하는 경우 캐스트를 모방하는 확장 메소드를 작성할 수 있습니다.
public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ...
return (T)o;
}
깔끔한 [?] 구문을 사용하십시오.
obj.To<SomeType>().SomeMethod()
답변
IMHO, 수표 as
와 함께 사용하는 것이 null
좋습니다.
var y = x as T;
if (y != null)
y.SomeMethod();
답변
‘as’를 사용하면 사용자 정의 전환이 적용되지 않지만 캐스트에서는 적절한 경우 전환을 사용합니다. 경우에 따라 중요한 차이가 될 수 있습니다.
답변
나는 이것에 대해 조금 썼다 :
나는 당신의 요점을 이해합니다. 캐스트 운영자는 “이 객체는 해당 유형으로 변환 될 수 있다고 확신하며, 틀린 경우 예외를 기꺼이 감수 할 것입니다”라는 의사 소통에 동의합니다. “이 개체가 해당 형식으로 변환 될 수 있는지 잘 모르겠습니다. 틀린 경우 null을 지정하십시오.”
그러나 미묘한 차이가 있습니다. (x는 T) .Whatever ()는 “x를 T로 변환 할 수있을뿐만 아니라 참조 또는 언 박싱 변환 만 포함하고, x가 null이 아니라는 것을 알고 있습니다.” 그것은 ((T) x) .Whatever ()와 다른 정보를 전달하며 아마도 코드 작성자가 의도 한 것입니다.
답변
나는 종종 “오직”이 캐스팅보다 빠르다는 증거 로이 잘못된 기사에 대한 언급을 보았다 .
이 기사에서 가장 오해의 소지가있는 부분 중 하나는 측정 대상을 나타내지 않는 그래픽입니다. 나는 실패한 캐스트를 측정하고 있다고 생각합니다 (예외가 발생하지 않아 “as”가 훨씬 빠릅니다).
측정하는 데 시간이 걸리면 예상대로 주조가 더 빠름을 알 수 있습니다 한대로 캐스팅이 성공할 때 캐스팅이 “as”보다 는 있습니다.
이것이 캐스트 대신에 as 키워드를 “cargo cult”로 사용하는 한 가지 이유 일 수 있습니다.
답변
직접 전송에는 as
키워드 보다 괄호 쌍이 더 필요 합니다. 따라서 유형이 무엇인지 100 % 확신하는 경우에도 시각적 혼란을 줄입니다.
그러나 예외적 인 것에 동의했다. 그러나 적어도 나를 위해, 대부분의 사용은 나중에 as
확인하기 위해 끓여서 null
예외를 잡는 것보다 더 좋습니다.
답변
“as”를 사용하는 시간의 99 %는 실제 객체 유형이 무엇인지 잘 모르겠습니다.
var x = obj as T;
if(x != null){
//x was type T!
}
“is”를 사용하여 명시적인 캐스트 예외를 포착하거나 두 번 캐스트하고 싶지 않습니다.
//I don't like this
if(obj is T){
var x = (T)obj;
}
