null 검사가없는 경우에도 캐스트 대신 "as"를 사용하는 것이 합리적입니까? [닫은]
개발 블로그, 온라인 코드 예제 및 (최근) 책에서도 다음과 같은 코드에 대해 계속 걸림돌이됩니다.
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;
}
사람들이 외모를 좋아하기 때문에 읽기 쉽습니다.
C와 유사한 언어의 캐스팅 / 변환 연산자는 가독성이 매우 뛰어납니다. C #이 다음 Javascript 구문 중 하나를 채택하면 더 좋습니다.
object o = 1;
int i = int(o);
또는 다음 to
과 같은 캐스팅을 갖는 연산자를 정의하십시오 as
.
object o = 1;
int i = o to int;
사람들 as
은 예외로부터 안전하다고 느끼기 때문에 너무 좋아 합니다. 남자는 당신이 상자 안에 따뜻하고 건장한 느낌을주기를 원하기 때문에 멋진 보증을합니다. 밤에 베개 아래에 작은 상자를 두었다고하자 보증 요정이 내려 와서 1/4을 떠날 수도 있습니다.
직접 캐스트를 사용할 때 돌아 가기 주제에 ...의 존재 가능성 잘못된 캐스트 예외는. 따라서 사람들 은 자체적으로 예외를 던지지 as
않기 때문에 모든 주조 요구에 담요 솔루션으로 적용 됩니다 as
. 그러나 재미있는 점은 예제 (x as T).SomeMethod();
에서 null 참조 예외에 대해 잘못된 캐스트 예외를 거래하고 있다는 것입니다. 예외를 볼 때 실제 문제를 난독 화시키는 것은 무엇입니까?
나는 일반적으로 as
너무 많이 사용하지 않습니다 . 나에게 is
테스트를 선호합니다. 더 읽기 쉽고 캐스트를 시도하고 null을 확인하는 것이 더 합리적입니다.
이것은 나의 최고 동료 중 하나 여야 합니다.
Stroustrup의 D & E 및 / 또는 내가 지금 찾을 수없는 블로그 게시물 to
은 https://stackoverflow.com/users/73070/johannes-rossel (즉, 의미론 as
과 동일한 구문 이지만) DirectCast
).
이것이 구현되지 않은 이유는 캐스트가 통증을 유발하고 추악 해져 사용하지 못하기 때문입니다.
'영리한'프로그래머 (종종 저술가 (Juval Lowy IIRC)) as
가 이런 방식 으로 학대함으로써이 문제를 해결하는 것이 유감입니다 (C ++은 as
아마도 이런 이유로을 제공하지 않습니다 ).
심지어 VB는 당신이를 선택하는 힘있는 균일 한 구문을 가지고 더 일관성이 TryCast
나 DirectCast
하고 당신의 마음을 확인을 !
나는 믿고 as
키워드가 좀 더 우아한 찾고 버전으로 간주 할 수있는 dynamic_cast
C ++에서.
기술적 인 이유는 없지만 읽기 쉽고 직관적이기 때문에 더 인기가있을 것입니다. (단지 질문에 대답하는 것이 더 나아지는 것은 아닙니다)
"as"를 사용하는 한 가지 이유 :
T t = obj as T;
//some other thread changes obj to another type...
if (t != null) action(t); //still works
(잘못된 코드) 대신 :
if (obj is T)
{
//bang, some other thread changes obj to another type...
action((T)obj); //InvalidCastException
}
'development' 카테고리의 다른 글
소프트웨어 라이센스 키는 어떻게 생성됩니까? (0) | 2020.03.01 |
---|---|
Firebase apiKey를 공개하는 것이 안전합니까? (0) | 2020.03.01 |
비동기 및 비 차단 (0) | 2020.03.01 |
JSON에서 null을 나타내는 (0) | 2020.03.01 |
Objective-C에서 클래스에 대한 개인 메소드를 정의하는 가장 좋은 방법 (0) | 2020.03.01 |