다음 코드를 고려하십시오.
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
. 그렇지 않으면, 양수인 o
에 s
, 경우에도이 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()
로 돌아가는 모든 것을 할당 합니다 .s
o
대부분의 전환에 1을 사용하면 간단하고 간단합니다. 무언가가 올바른 유형이 아닌 경우 일반적으로 예외가 발생할 것으로 기대하기 때문에 거의 2를 사용하지 않는 경향이 있습니다. 오류 코드를 사용하는 잘못 설계된 라이브러리 (예 : 예외를 사용하는 대신 null = error를 반환)를 사용하여이 반환 null 유형의 기능에 대한 필요성 만 보았습니다.
3은 캐스트가 아니며 메소드 호출입니다. 문자열이 아닌 객체의 문자열 표현이 필요할 때 사용하십시오.
답변
string s = (string)o;
무언가 다른 것이 분명 해야 할 때 사용하십시오
.string s = o as string;
다른 것이 있을 때 사용하십시오 .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
에는가 있으므로 o
null이 아닌 경우 세 번째 메소드는 괜찮을 수 있으며 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();
최소한의 캐스트 로 먹이를 얻 습니다 .