[C#] 다이렉트 캐스팅 대 ‘as’연산자?

다음 코드를 고려하십시오.

void Handler(object o, EventArgs e)
{
   // I swear o is a string
   string s = (string)o; // 1
   //-OR-
   string s = o as string; // 2
   // -OR-
   string s = o.ToString(); // 3
}

세 가지 유형의 캐스팅의 차이점은 무엇입니까? 어느 것을 선호해야합니까?



답변

string s = (string)o; // 1

예외 InvalidCastException이를 경우 o하지 않은 것입니다 string. 그렇지 않으면, 양수인 os, 경우에도이 o있다 null.

string s = o as string; // 2

를 할당 null하는 s경우 o없는 string경우, 또는 o이다 null. 따라서 값 유형과 함께 사용할 수 없습니다 (이 경우 연산자는 절대 리턴 할 수 없음 null). 그렇지 않으면에 할당 o합니다 s.

string s = o.ToString(); // 3

원인 NullReferenceException이 있는 경우 o입니다 null. 유형 이 무엇 이든 관계없이 o.ToString()로 돌아가는 모든 것을 할당 합니다 .so


대부분의 전환에 1을 사용하면 간단하고 간단합니다. 무언가가 올바른 유형이 아닌 경우 일반적으로 예외가 발생할 것으로 기대하기 때문에 거의 2를 사용하지 않는 경향이 있습니다. 오류 코드를 사용하는 잘못 설계된 라이브러리 (예 : 예외를 사용하는 대신 null = error를 반환)를 사용하여이 반환 null 유형의 기능에 대한 필요성 만 보았습니다.

3은 캐스트가 아니며 메소드 호출입니다. 문자열이 아닌 객체의 문자열 표현이 필요할 때 사용하십시오.


답변

  1. string s = (string)o;무언가 다른 것이 분명 해야 할 때 사용하십시오
    .
  2. string s = o as string;다른 것이 있을 때 사용하십시오 .
  3. string s = o.ToString(); 그것이 무엇인지 상관하지 않지만 사용 가능한 문자열 표현을 사용하려는 경우에 사용하십시오.

답변

o문자열 인지 알고 있는지 여부 와 문자열로 수행하려는 작업 에 따라 다릅니다 . 귀하의 의견이 o실제로 문자열 이라는 것을 의미 하는 경우 스트레이트 (string)o캐스트를 선호합니다 . 실패하지 않을 것입니다.

스트레이트 캐스트를 사용하는 것의 가장 큰 장점은 실패했을 때 InvalidCastException 을 얻는다 는 것입니다.

으로 as하면 연산자, o문자열이 아닌, s설정되어 null당신이 확실하고 테스트하려는 경우 편리되는 s:

string s = o as string;
if ( s == null )
{
    // well that's not good!
    gotoPlanB();
}

그러나 해당 테스트를 수행하지 않으면 s나중에 사용 하고 NullReferenceException이 발생합니다. 거의 모든 행이 변수를 역 참조하고 하나를 던질 수 있기 때문에 이러한 변수 는 일반적으로 발생하고 일단 야생에서 발생하면 추적하기가 훨씬 어렵습니다. 반면에, 값 유형 (기본 또는 DateTime 과 같은 구조체 )으로 캐스트하려는 경우 스트레이트 캐스트를 사용해야합니다 as.

문자열로 변환하는 특별한 경우 모든 객체 ToString에는가 있으므로 onull이 아닌 경우 세 번째 메소드는 괜찮을 수 있으며 ToString메소드가 원하는 것을 할 수 있다고 생각합니다 .


답변

어떤 유형으로 캐스트 할 수 있는지 이미 알고 있다면 C 스타일 캐스트를 사용하십시오.

var o = (string) iKnowThisIsAString; 

C 스타일 캐스트에서만 명시 적 유형 강제 변환을 수행 할 수 있습니다.

이 원하는 형식이고 당신이 그것을 사용하는 경우이를 사용하려고하고 있는지 당신이 모르는 경우 등의 키워드 :

var s = o as string;
if (s != null) return s.Replace("_","-");

//or for early return:
if (s==null) return;

참고 모든 종류의 변환 연산자를 호출하지 않습니다. 객체가 null이 아니고 기본적으로 지정된 유형이 아닌 경우에만 null이 아닙니다.

문자열로 캐스트 할 수없는 경우에도 ToString ()을 사용하여 사람이 읽을 수있는 모든 문자열 표현을 가져옵니다.


답변

as 키워드는 FindControl 메서드를 사용할 때 asp.net에서 좋습니다.

Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
     ...
}

object, 직접 캐스트와 마찬가지로 유형이 지정된 변수를 조작 한 다음 캐스트해야합니다 .

object linkObj = this.FindControl("linkid");
if (link != null)
{
     Hyperlink link = (Hyperlink)linkObj;
}

큰 것은 아니지만 코드 라인과 변수 할당을 저장하고 더 읽기 쉽습니다.


답변

‘as’는 ‘is’를 기반으로하며, 이는 객체가 정책적으로 호환 가능한지 (기본적으로 캐스트 할 수있는 경우) 런타임에 확인하고 확인에 실패하면 null을 반환하는 키워드입니다.

이 두 가지는 동일합니다.

‘as’사용 :

string s = o as string;

‘is’사용하기 :

if(o is string)
    s = o;
else
    s = null;

반대로 c 스타일 캐스트는 런타임에도 수행되지만 캐스트를 수행 할 수없는 경우 예외가 발생합니다.

중요한 사실을 추가하기 만하면됩니다.

‘as’키워드는 참조 유형에서만 작동합니다. 당신은 할 수 없습니다 :

// I swear i is an int
int number = i as int;

이 경우 캐스팅을 사용해야합니다.


답변

2는 파생 형식으로 캐스팅하는 데 유용합니다.

a 가 동물 이라고 가정 하십시오 .

b = a as Badger;
c = a as Cow;

if (b != null)
   b.EatSnails();
else if (c != null)
   c.EatGrass();

최소한의 캐스트 먹이를 얻 습니다 .