2013-11-20 3 views
3

첫 번째 코드 줄에서 컴파일러 오류를 일으키는 이유와 다음 코드가 아닌 이유를 설명 할 수 있습니까?캐스팅 제네릭 매개 변수

public void DoStuff<T>(T obj) 
{ 
Int32 x = (Int32) obj; // 1. Error 
Int32 y=(Int32)(Object)obj; //2. Works fine 
} 
+0

OBJ의 종류는 숫자 것으로 알려진 때 고려 때문에 그러나, 그것은 이 아닌 것 타입의 T입니다 당신이 그것을 통과 할 때이 아닌 Object 형식, 당신 때문에 전에 그것을 반대해야합니다. T 대신 Object를 사용하면 두 줄 모두 제대로 작동합니다. –

+0

잘 모르겠지만 시도해 보는 것이 좋습니다. 캐스트가 런타임에 실패하지 않는다는 것을 어떻게 알 수 있습니까? Int32.TryParse 또는 이벤트 Convert.ToInt32를 사용하지 않는 이유는 무엇입니까? – Wjdavis5

답변

4

캐스팅하려면 컴파일 타임에 한 유형에서 다른 유형으로 변환하는 방법을 알아야합니다. 예를 들면 :

컴파일러는 intlong을 주조하는 방법을 알고 있기 때문에이 작동
long l = 34; 
int i = (int)l; 

. 그러나

object o = 42; 
int i = (int)o; 

, 모든 종류의 int에 캐스트 할 수 없습니다 :

string s = "48"; 
int i = (int)s; // This will not compile. 

당신의 모든 유형을 나타낼 수있는 일반, 당신은 단지에 캐스트 할 수 없기 때문에 그것은 또한 objectint로 변환하는 방법을 알고 int 모든 유형에 대해 모두 엎질러 져 있습니다. 너는 먼저 그걸 던져서 int에 던져 넣을 수있는 뭔가에 던져 넣어야 해. 무엇이든 objectobject으로 캐스트 할 수 있고 무엇이든 캐스트 될 수 있으므로 두 번 캐스트하면됩니다. 다른 유형 제네릭 형식 변수를 주조

+0

@ Wjdavis5는 그의 의견에 좋은 점을 가지고 있습니다. 이것은 객체가 실제로 int 인 경우에만 작동합니다. 선행을 알고 있다면, 처음에는'T'가 필요하지 않습니다. 퍼지 일치 (아마도 문자열 또는 double 또는 무언가)라면 'Convert.ToInt32'가 더 나은 접근 방법 일 것입니다. –

+0

이 답변은 "캐스트"와 "변환"이라는 용어가 섞여있는 것 같습니다. – Servy

+0

@Joe 동의합니다. 제네릭은 전달 된 형식이 어떤 종류의 오류없이 코드 줄을 실행할 수있는 경우에만 사용해야합니다. 나는 단지 instanceOf가 그의 문제를 해결할 수 있다고 생각합니다. –

0

제한 조건과 호환되는 유형으로 변환하지 않는 한 불법입니다 : T는 어떤 유형이 될 수 있기 때문에 컴파일러는 위의 두 라인에서 오류가 발생

private static void CastingAGenericTypeVariable1<T>(T obj) { 
Int32 x = (Int32) obj; // Error 
String s = (String) obj; // Error 
} 

하고, 캐스트가 성공할 것임을 보장하는 이 없습니다. 당신은 처음 Object로 변환하여 컴파일 얻기 위해이 코드를 수정할 수 있습니다

private static void CastingAGenericTypeVariable2<T>(T obj) { 
    Int32 x = (Int32) (Object) obj; // No error 
    String s = (String) (Object) obj; // No erro``r 
    } 

이 코드는 이제 컴파일하는 동안, CLR 런타임에 InvalidCastException이 던져하는 것이 여전히 가능하다.

참조 유형으로 변환하려는 경우 C# as 연산자를 사용할 수도 있습니다. 다음 코드는 문자열 연산자로를 사용하는 수정 (INT32은 값 형식이기 때문에) :

private static void CastingAGenericTypeVariable3<T>(T obj) { 
    String s = obj as String; // No error 
    } 

This is from CLR via C# 
0

T은 어떤 유형이 될 수는 있지만, 컴파일러는 Int32 하드 캐스트 따라서 컴파일, 특정 유형의 작동을 인식 오류.

0

제네릭 메서드가있는 경우 int로 캐스팅하지 않으실 수 있습니다. 오버로드 또는 다른 접근법을 통해이를 수행하는 더 좋은 방법은 거의 확실합니다. 그러나

... 당신은 안전하게 다음 두 가지 방법 중 하나를 할 수있는이 작업을 수행 할 필요가 결정하는 경우에 ...

if (obj is Int32) 
{ 
    // do stuff 
} 

나 ..

Int32? z = obj as Int32? 
if (z != null) 
{ 
    // do stuff 
} 
0

사양이 설명 행동 :

6.2.유형을 포함하는 7 명시 전환은 놀라운 수 있습니다 비 인터페이스 유형에 구속 유형 매개 변수에서 직접 명시 적 변환을 허용하지 않습니다

위의 규칙을 매개 변수. 이 규칙의 이유는 혼동을 방지하고 이러한 변환의 의미를 명확하게하기위한 것입니다. 쉽게 그 X.F (7) 7L을 반환 예상 일톤의 직접 명시 적 변환이 허용 된 int로하면

class X<T> 
{ 
    public static long F(T t) { 
     return (long)t;    // Error 
    } 
} 

, 예를 들어, 다음 선언을 고려하십시오. 표준 숫자 변환은 바인딩 시간