문제

가능한 중복:
CLR에서 캐스팅과 'as' 키워드 사용 비교

실제로 이 두 캐스트의 차이점은 무엇입니까?

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

일반적으로 둘 다 지정된 유형에 대한 명시적 캐스트여야 합니까?

도움이 되었습니까?

해결책

전자는 소스 유형을 대상 유형으로 변환할 수 없는 경우 예외를 발생시킵니다.후자의 경우 sc2는 null 참조가 되지만 예외는 아닙니다.

[편집하다]

내 원래 대답은 확실히 가장 뚜렷한 차이점이지만 Eric Lippert는 지적, 그것만이 아닙니다.다른 차이점은 다음과 같습니다.

  • 'null'을 값으로 허용하지 않는 유형으로 캐스팅하기 위해 'as' 연산자를 사용할 수 없습니다.
  • 'as'를 사용할 수 없습니다. 전환하다 숫자를 다른 표현으로 표현하는 것(예를 들어 float를 int로).

그리고 마지막으로 'as'와 'as'를 사용하여캐스트 연산자를 사용하면 "이것이 성공할지 확신할 수 없습니다."라고 말하고 있는 것입니다.

다른 팁

또한 참조 유형 또는 null 허용 유형에만 as 키워드를 사용할 수 있습니다.

즉:

double d = 5.34;
int i = d as int;

컴파일되지 않습니다

double d = 5.34;
int i = (int)d;

컴파일됩니다.

물론 "as"를 사용하는 타입 캐스팅은 예외를 발생시키는 비용을 피하기 때문에 캐스팅이 실패할 때 훨씬 더 빠릅니다.

하지만 시전이 성공한다고 해서 속도가 빨라지는 것은 아닙니다.그래프는 http://www.codeproject.com/KB/cs/csharpcasts.aspx 측정 대상을 설명하지 않기 때문에 오해의 소지가 있습니다.

결론은 다음과 같습니다.

  • 캐스트가 성공할 것으로 예상되는 경우(예:실패는 예외적입니다.) 캐스트를 사용하십시오.

  • 성공할지 여부를 알 수 없는 경우 "as" 연산자를 사용하고 결과가 null인지 테스트하세요.

두 접근 방식의 차이점은 첫 번째 ((SomeClass)obj)가 유형 변환기 호출됩니다.

내 상황에 어떤 것이 더 나은지 결정할 때 사용하는 각각의 프로세스를 기억하는 좋은 방법은 다음과 같습니다.

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

다음은 무엇을 하는지 추측하기 쉬울 것입니다

DateTime i = value as DateTime;

첫 번째 경우에는 값을 캐스팅할 수 없으면 예외가 발생합니다. 두 번째 경우에는 값을 캐스팅할 수 없으면 i가 null로 설정됩니다.

따라서 첫 번째 경우에는 두 번째 캐스팅에서 캐스팅이 실패하면 하드 중지가 이루어지며 소프트 중지가 이루어지고 나중에 NullReferenceException이 발생할 수 있습니다.

'as' 연산자는 문제를 훨씬 더 낮게 묻어두는 데 도움이 됩니다. 호환되지 않는 인스턴스가 제공되면 null을 반환할 수 있고, 이를 다른 메서드에 전달하는 등의 방식으로 메서드에 전달하고 마지막으로 디버깅을 더 어렵게 만드는 NullReferenceException을 받게 되기 때문입니다.

그것을 남용하지 마십시오.99%의 경우 직접 캐스트 연산자가 더 좋습니다.

확장하려면 Rytmis의 코멘트, 당신은 사용할 수 없습니다 ~처럼 null 값이 없기 때문에 구조체(값 유형)에 대한 키워드입니다.

이 모든 것은 참조 유형에 적용되며 값 유형은 as 키워드는 null이 될 수 없습니다.

//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;


//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;

캐스트 구문은 더 빠르지만 성공할 때만 실패하는 속도가 훨씬 느립니다.

가장 좋은 방법은 다음을 사용하는 것입니다. as 유형을 모를 때:

//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;

//use as to find the right type
if( ( sc = someObject as SomeClass ) != null ) 
{
    //do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null ) 
{
    //do something with soc
}

그러나 당신이 그것을 절대적으로 확신한다면 someObject 의 사례이다 SomeClass 그런 다음 캐스트를 사용하십시오.

.Net 2 이상의 제네릭은 참조 클래스의 유형이 지정되지 않은 인스턴스를 가질 필요가 거의 없음을 의미하므로 후자는 덜 자주 사용됩니다.

캐스트 시도가 실패하면 괄호 안에 있는 캐스트에서 예외가 발생합니다."as" 캐스트는 캐스트 시도가 실패할 경우 null을 반환합니다.

그들은 다른 예외를 던질 것입니다.
() :NullReferenceException
처럼 :InvalidCastException
디버깅에 도움이 될 수 있습니다.

"as" 키워드는 객체 캐스팅을 시도하며 캐스팅이 실패하면 null이 자동으로 반환됩니다.() 캐스트 연산자는 캐스트가 실패하면 즉시 예외를 발생시킵니다.

"예외적이지 않은 경우에 캐스팅이 실패할 것으로 예상되는 경우에만 C# "as" 키워드를 사용하세요.캐스트가 성공할 것으로 기대하고 실패할 개체를 받을 준비가 되어 있지 않은 경우 적절하고 유용한 예외가 발생하도록 () 캐스트 연산자를 사용해야 합니다."

코드 예제 및 추가 설명은 다음을 참조하세요. http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

Parse와 TryParse의 차이점과 같습니다.실패할 것으로 예상되면 TryParse를 사용하지만, 실패하지 않을 것이라는 강한 확신이 있으면 Parse를 사용합니다.

VB.NET 경험이 있는 분들을 위해 (type)은 DirectCast와 동일하고 "as type"은 TryCast와 동일합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top