C # "as"캐스트와 클래식 캐스트
중복 가능성 :
캐스팅과 CLR에서 'as'키워드 사용
최근에 다른 캐스팅 방법에 대해 배웠습니다. 사용하기보다는
SomeClass someObject = (SomeClass) obj;
이 구문을 사용할 수 있습니다 :
SomeClass someObject = obj as SomeClass;
obj가 클래스 캐스트 예외를 던지기보다는 SomeClass가 아닌 경우 null을 반환하는 것 같습니다.
캐스트가 실패하고 someObject 변수에 액세스하려고하면 NullReferenceException이 발생할 수 있음을 알았습니다. 그래서이 방법의 근거가 무엇인지 궁금합니다. 왜 (오래된) 캐스팅이 아닌이 캐스팅 방식을 사용해야합니까? 실패한 캐스트 문제를 "더 깊은"코드로 옮기는 것 같습니다.
"클래식"방법으로 캐스트에 실패하면 예외가 발생합니다. as 메소드를 사용하면 null이 발생하여 확인할 수 있으며 예외가 발생하지 않습니다.
또한 참조 형식에는 "as"만 사용할 수 있으므로 값 형식으로 형식을 변환하는 경우 "classic"메서드를 사용해야합니다.
노트 :
이 as
방법은 null
값을 할당 할 수있는 유형에만 사용할 수 있습니다 . 이는 참조 유형만을 의미하는 것이지만 .NET 2.0이 나왔을 때 널 입력 가능 유형 개념을 도입했습니다. 이러한 유형에는 null
값을 지정할 수 있으므로 as
연산자 와 함께 사용할 수 있습니다.
예외를 던지고 잡는 것보다 Null 비교가 훨씬 빠릅니다. 예외에는 상당한 오버 헤드가 있습니다-스택 추적 등을 조립해야합니다.
예외는 예기치 않은 상태를 나타내며 상황을 나타내지 않는 경우가 많습니다 ( as
더 나은 경우).
경우에 null
따라 예외보다 쉽게 처리 할 수 있습니다 . 특히 통합 연산자는 다음과 같이 편리합니다.
SomeClass someObject = (obj as SomeClass) ?? new SomeClass();
또한 객체의 유형에 따라 (다형성을 사용하지 않고) 분기하는 코드를 단순화합니다.
ClassA a;
ClassB b;
if ((a = obj as ClassA) != null)
{
// use a
}
else if ((b = obj as ClassB) != null)
{
// use b
}
온 따른다 MSDN 페이지 의 as
운영자는 동등하다 :
expression is type ? (type)expression : (type)null
이는 더 빠른 유형 테스트를 위해 예외를 완전히 피할 수 있지만 지원하는 유형 null
(참조 유형 및 Nullable<T>
) 으로 사용을 제한합니다 .
as
운영자는 상황의 몇 유용합니다.
- 객체가 특정 유형임을 알 필요가 있지만 해당 유형의 멤버에 대해 구체적으로 행동 할 필요가없는 경우
- 예외를 피하고 대신 명시 적으로 처리하고 싶을 때
null
- 사용자 정의 변환뿐만 아니라 개체간에 CLR 변환이 있는지 알고 싶습니다.
세 번째 요점은 미묘하지만 중요합니다. 캐스트 연산자와 캐스트가 성공할 연산자와 연산자와 성공할 캐스트 사이에는 1-1 맵핑이 없습니다 as
. as
운영자는 엄격하게 CLR 변환에 제한되며 (캐스트 연산자 것) 사용자 정의 변환을 고려하지 않을 것이다.
특히 as
연산자는 다음을 허용합니다 (C # lang 사양의 섹션 7.9.11부터).
- 신원 (§6.1.1), 암시 적 참조 (§6.1.6), 권투 (§6.1.7), 명시 적 참조 (§6.2.4) 또는 언 박싱 (§6.2.5) 변환은 E 유형에서 존재합니다. T에게
- E 또는 T의 유형은 개방형입니다.
- E는 널 리터럴입니다.
as
키워드는 진정 경우에 유용 모르는 변수가 될 수 입력 한 내용. 매개 변수의 실제 유형에 따라 다른 코드 경로를 따르는 단일 함수가있는 경우 두 가지 선택 사항이 있습니다.
먼저 일반 캐스트를 사용하십시오.
if(myObj is string)
{
string value = (string)myObj;
... do something
}
else if(myObj is MyClass)
{
MyClass = (MyClass)myObj;
}
이를 위해서는 객체의 유형을 검사하여 is
실패한 것으로 캐스팅하지 않도록해야합니다. is
-type 검사가 캐스트에서 다시 수행되므로 필요한 경우 예외가 발생할 수 있으므로 약간 중복됩니다 .
대안은을 사용하는 것 as
입니다.
string myString = myObj as string;
MyClass myClass = myObj as MyClass;
if(myString != null)
{
}
else if(myClass != null)
{
}
이렇게하면 코드가 다소 짧아지고 중복 유형 검사도 제거됩니다.
using as will return null if not a valid cast which allows you to do other things besides wrapping the cast in a try/catch. I hate classic cast. I always use as cast if i'm not sure. Plus, exceptions are expensive. Null checks are not.
I think the best 'rule' would be to only use the 'as' keyword when it's expected that your subject won't be the object you're casting to:
var x = GiveMeSomething();
var subject = x as String;
if(subject != null)
{
// do what you want with a string
}
else
{
// do what you want with NOT a string
}
However, when your subject SHOULD be of the type you're casting to, use a 'classic cast', as you call it. Because if it isn't the type you're expecting, you'll get an exception which fits the exceptional situation.
There's nothing deep happening here.. Basically, it's handy to test something to see if it's of a certain type (i.e. use 'as'). You would want to check the result of the 'as' call to see if the result is null.
When you expect a cast to work and you want the exception to be thrown, use the 'classic' method.
You use the "as" statement to avoid the possibility of an exception, e.g. you can handle the cast failure gracefully via logic. Only use the cast when you are sure that the object is of the desired type. I almost always use the "as" and then check for null.
I suppose it is useful if the result of the cast will be passed to a method that you know will handle null references without throwing and ArgumentNullException
or suchlike.
I tend to find very little use for as
, since:
obj as T
Is slower than:
if (obj is T)
...(T)obj...
The use of as
is very much an edge-case scenario for me, so I can't think of any general rules for when I would use it over just casting and handling the (more informative) casting exception further up the stack.
참고URL : https://stackoverflow.com/questions/4926677/c-sharp-as-cast-vs-classic-cast
'Programing' 카테고리의 다른 글
마크 다운 새 창 링크 열기 (0) | 2020.07.01 |
---|---|
자바 스크립트는 함수형 프로그래밍 언어입니까? (0) | 2020.07.01 |
모델 및 관계 필드 이름 바꾸기를위한 장고 마이그레이션 전략 (0) | 2020.06.30 |
서비스가 항상 DTO를 반환해야합니까, 아니면 도메인 모델을 반환 할 수 있습니까? (0) | 2020.06.30 |
문자열 상수에서 'char *'로의 변환이 C에서는 유효하지만 C ++에서는 무효 인 이유 (0) | 2020.06.30 |