programing tip

캐스팅 : (NewType) 대 개체를 NewType으로

itbloger 2020. 9. 19. 10:13
반응형

캐스팅 : (NewType) 대 개체를 NewType으로 [중복]


중복 가능성 :
CLR에서 'as'키워드 사용 및 캐스팅

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

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

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


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

[편집하다]

내 원래 대답은 확실히 가장 두드러진 차이점이지만 Eric Lippert가 지적했듯이 유일한 대답은 아닙니다. 다른 차이점은 다음과 같습니다.

  • 값으로 'null'을 허용하지 않는 유형으로 캐스트하기 위해 'as'연산자를 사용할 수 없습니다.
  • 'as'를 사용하여 숫자와 같은 것을 다른 표현 으로 변환 할 수 없습니다 (예 : 부동 소수점에서 정수로).

마지막으로 'as'대 캐스트 연산자를 사용하면 "성공할지 모르겠습니다."라고 말합니다.


또한 참조 유형 또는 nullable 유형과 함께 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이 발생할 수 있습니다.


그런데 운전자가 "도움" '로'당신이 낮은 문제의 방법을 묻어 그것이 널 (null)을 반환합니다 호환되지 않는 인스턴스가 제공 될 때, 어쩌면 당신이 통과 할 것이기 때문에 방법에 등등 그리고 마지막으로 서로를 통과 할 것을 당신 ' 디버깅을 더 어렵게 만드는 NullReferenceException이 발생합니다.

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


Rytmis의 주석 을 확장하려면 null 값이 없기 때문에 구조체 (값 유형)에 as 키워드를 사용할 수 없습니다 .


이 모든 것은 참조 유형에 적용되며 값 유형은 asnull 일 수 없으므로 키워드를 사용할 수 없습니다.

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


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

캐스트 구문은 더 빠르지 만 성공한 경우에만 실패하는 것이 훨씬 느립니다.

Best practice is to use as when you don't know the type:

//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
}

However if you are absolutely sure that someObject is an instance of SomeClass then use cast.

In .Net 2 or above generics mean that you very rarely need to have an un-typed instance of a reference class, so the latter is less often used.


The parenthetical cast throws an exception if the cast attempt fails. The "as" cast returns null if the cast attempt fails.


They'll throw different exceptions.
() : NullReferenceException
as : InvalidCastException
Which could help for debugging.

The "as" keyword attempts to cast the object and if the cast fails, null is returned silently. The () cast operator will throw an exception immediately if the cast fails.

"Only use the C# "as" keyword where you are expecting the cast to fail in a non-exceptional case. If you are counting on a cast to succeed and are unprepared to receive any object that would fail, you should use the () cast operator so that an appropriate and helpful exception is thrown."

For code examples and a further explanation: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html


It's like the difference between Parse and TryParse. You use TryParse when you expect it might fail, but when you have strong assurance it won't fail you use Parse.


For those of you with VB.NET experience, (type) is the same as DirectCast and "as type" is the same as TryCast.

참고URL : https://stackoverflow.com/questions/2483/casting-newtype-vs-object-as-newtype

반응형