Microsoft MVP성태의 닷넷 이야기
캐스팅...에 관해 궁금합니다. [링크 복사], [링크+제목 복사],
조회: 18237
글쓴 사람
edain
홈페이지
첨부 파일
 

안녕하세요.

C#에서는

int n = 3;
object o = n;
int m = (int)o;

위와 같이 object로 변환된 값을 실제 타입으로 캐스팅 하려면 코딩할 때 타입을 알고 있어야 캐스팅이 가능해 보입니다.
만약에 위의 코드에서 int m = o; 라고 쓰면 오류가 나죠.

하지만 VB.NET 에서는 위의 코드를 아래와 같이 변환하면

Dim n As Integer = 3
Dim o As Object = n    
Dim m As Integer = o

잘 작동합니다.

리플렉션을 해 보면 VB.NET에서는 따로 Microsoft.VisualBasic.CompilerServices.Conversions.ToInteger 라는 메서드를 사용해서 변환을 해 주는 것 같습니다.

C#에서는 위와같은 코드를 작성하려면 어떻게 해야 할까요?









[최초 등록일: ]
[최종 수정일: 9/8/2015]


비밀번호

댓글 작성자
 



2015-09-08 01시53분
VB.NET과 C#은 언어의 철학이 다릅니다. 그래서 그런 차이가 발생하는 것입니다. 제가 이전의 VB 6을 잘 몰라서 정확한 답은 아닐 수 있는데, 아마도 VB 시절부터 그 구문이 동작했기 때문에 VB.NET에서 뺄 수 없어서 가능하도록 구현했을 것입니다. (Microsoft.VisualBasic 네임스페이스에 포함된 것들은 대부분 기존 VB와의 호환을 위해 만들어 둔 것입니다.)

VB.NET은 대입될 대상 변수가 Integer이기 때문에 무조건 (성공하든 못하든) ToInteger를 불러주도록 코드를 생성해주는 것입니다. 반면, C#은 object에 어떤 타입의 인스턴스가 들어 있을지 알 수 없기 때문에 암시적 형변환이나 ToInteger 같은 메서드로 대체하지 않고 개발자의 책임하에 명시적으로 형변환을 하도록 강제하는 것입니다. (이는 C++과도 유사한 정책입니다.)
정성태
2015-09-08 02시47분
[edain] 네.. 답변 감사드립니다.^^

이러한 의문이 발생한 원인은 오래전 DataTable 로 Query 의 결과를 조회해 오고는 행마다 대응되는 클래스의 인스턴스로 생성하는 일을 하면서였습니다.
쿼리에 대응되는 클래스가 많아지자 귀찮아서 Reflection으로 DataTable의 Column Name과 똑같이 대응되는 Property Name으로 값을 넘겨 자동화를 하였었습니다.
그런데 문제는 PropertyInfo 로 대상 클래스의 Property에 값을 SetValue 메서드를 사용하려니 매개변수 타입이 object 이더라구요.
PropertyInfo를 설계하신 분 입장에선 당연히 어떤 타입의 값이 사용될지 모르는 상황에서 당연한 문제였을 것 같지만 이런식으로 쓰면 Boxing 이 많이 발생되지 않을까 하는 의문도 들었고 이런 방식 말고는 방법이 없을까? 하는 의문도 들었었습니다. 그러다가 오늘 비슷한 문제를 누군가가 이야기 하시길래 제 의문과 함께 질문을 드렸습니다.^^



[guest]
2015-09-08 04시43분
해당 문제의 박싱/언박싱이라면, VB.NET에서도 (코드에서 그것이 숨겨질 뿐) 동일하게 나타납니다.

그러게요. ^^ 자동화와 성능을 같이 잡는 것이 쉽지는 않은 것 같습니다. DataTable과 대응 클래스 같은 경우에는, 저는 예전에 "자동 소스 코드 생성기"로 처리를 했었습니다. XML로 클래스의 규격을 표현하고 그것을 XSLT를 이용해 DataTable과 대응 클래스를 자동으로 생성하게 하는 것인데, 그럴 때 XmlCodeGenerator를 써먹었습니다.

XmlCodeGenerator
; https://visualstudiogallery.msdn.microsoft.com/20163975-c675-4f1c-986f-d2489136469d
정성태
2015-09-10 06시30분
[edain] XmlCodeGenerator에 관한 글을 오래전에 성태님 글에서 본 건지...왠지 낯이 익네요^^ 감사합니다.

박싱은/언박싱은 어쩔 수 없다고 생각하고 타입을 변경하는 코드를 만들어봤습니다.
사실 위의 질문에서의 지역변수형태의 변수들은 속성으로 실제 만들어져 있는데요.
리플렉션으로 속성..즉 Property의 PropertyInfo 를 얻어와선 SetValue 메서드와 Convert.ChangeType 메서드를 사용하면 인스턴스 값의 실제 타입이 일치하든 아니든 변경은 이루어지네요.
다들 알고 계실 듯 하지만 혹여나 저처럼 고민하시는 분들이 계시면 도움이 될까 싶어 남겨 봅니다.

처음에 Convert.ChangeType 메서드를 봤을 때 어차피 타입을 변경해줘봤자 object로 반환하는데 이게 무슨 쓸모가 있지? 라는 생각이 들었었습니다.
그런데 아는 형의 리플렉션 예제 코드를 도와주며 대화를 하다보니 PropertyInfo의 SetValue는 object 타입의 값을 받아 내부적으로 실제 타입으로 변환해준다는 사실이 생각났습니다.
왜 이 생각이 이제야 났는지 참 바보같다고 생각한 오후입니다. ㅜㅜ

아래의 코드는 LINQPAD의 코드입니다.

void Main()
{
    TypeA a = new TypeA();
    a.Value = 3;
    
    TypeB b = new TypeB();
    
    // b.Value = Convert.ChangeType(a.Value, typeof(string)); // 오류. 당연한 이야기이지만 원본 데이터와 대상 속성의 타입이 다름으로 실행 불가.
    // b.Value = (string)Convert.ChangeType(a.Value, typeof(string)); // 잘 작동함. 하지만 코딩할 때 타입을 일일이 쓰는 경우가 아니고 동적 변환에는 무슨타입이 올지 알 수 없으므로 쓸모없음.
    
    // solution
    PropertyInfo piValue = b.GetType().GetProperty("Value");
    
    // piValue.SetValue(b, a.Value); // 이 코드는 원래 타입이 Int32 이기 때문에 string 값으로 대입불가
    piValue.SetValue(b, Convert.ChangeType(a.Value, piValue.PropertyType));
    
    b.Value.Dump();    
}

// Define other methods and classes here


public class TypeA
{
    public int Value { get; set; }
}

public class TypeB
{
    public string Value { get; set; }
}
[guest]
2015-09-10 06시36분
[edain] 헉...댓글이 중복이 되어버린...ㅜㅜ 하나 지워주실 수 있을까요?
아뭏든 Convert.ChangeType 이 이런 경우에는 매우 유용하게 사용될 수 있음을 이제야 깨닳은 1人 입니다.ㅜㅜ
[guest]

... 76  77  78  79  80  81  [82]  83  84  85  86  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
431혁이7/19/200612248UpdatePanel(Atlas)위의 SmartClient가 이벤트후 사라집니다. ㅜㅜ파일 다운로드1
432정성태7/19/200612620    답변글 [답변]: UpdatePanel(Atlas)위의 SmartClient가 이벤트후 사라집니다. ㅜㅜ
433혁이7/20/200613472        답변글 [답변]: [답변]: UpdatePanel(Atlas)위의 SmartClient가 이벤트후 사라집니다. ㅜㅜ
434정성태7/20/200614221            답변글 [답변]: [답변]: [답변]: UpdatePanel(Atlas) 위의 SmartClient가 이벤트 후 사라집니다. ㅜㅜ [1]
429kwt7/12/200613514ActiveX 개발을 배우고 싶은데요 [3]
427이홍자7/11/200613799스마트 클라이언트 실행 시 그리드의 체크박스가 안보여요.. [1]
426정보문7/11/200614339액티브X 설치2 [1]
423이방은7/9/200613219리소스 임베디드 질문요.. [1]파일 다운로드1
422guest7/6/200612801COM+에서 풀링을 사용할 경우... [1]파일 다운로드1
424guest7/10/200613659    답변글 소스 코드 입니다. [1]
425guest7/11/200613072        답변글 다시 올립니다.파일 다운로드1
428정성태7/11/200612911            답변글 [답변]: 다시 올립니다.
421정보문7/6/200613459액티브X 설치 [1]
1354허재호11/12/201414094    답변글 [답변]: 액티브X 설치
418임대진7/4/200612670이럴적 있으세요?
419정성태7/4/200612825    답변글 [답변]: 이럴적 있으세요?
417이방은6/29/200612566[질문]2.0에서 웹리소스에 대해서 [2]
416박영일6/29/200612801CAS 설정여부 [1]
415김인학6/28/200613329스마트 클라이언트에서 웹서비스를 호출하고 있습니다. [1]
413김성호6/28/200613011IE프로그램문제... [2]
411이진형6/27/200613197어셈블리 네임 알아내기 [2]
414정성태6/28/200612409    답변글 [답변]: 어셈블리 네임 알아내기
410이재원6/26/200612583자바스크립트 스마트클라이언트 이벤트 호출 [3]
412이재원6/27/200612690    답변글 [답변]: 자바스크립트 스마트클라이언트 이벤트 호출
409정준명6/22/200613652윈폼 기반 스마트클라이언트 속도 문제에 대해서 의견을 구합니다. [2]
406이진형6/21/200613842처음에 스마트클라이언트 로딩하는 속도 [1]
... 76  77  78  79  80  81  [82]  83  84  85  86  87  88  89  90  ...