2011-12-01 12 views
3

사전 <문자열, 개체>에 사전 <문자열, MyClass에> 주조 방법 : I 유형 BagB의 객체를 만드는거야 반사를 통해 내가 을 지금나는 다음과 같은 클래스했다

public class BagA : Dictionary<string, BagB> 
{} 
public class BagB : Dictionary<string, object> 
{} 

해요

object MyBagA // Created through reflection 
object MyBagB // Created through reflection 

((Dictionary<string,object>)MyBagA).Add("123",MyBagB); //This doesnt work 

나에게 다음과 같은 오류 제공합니다 : 내가 형 바가으로 만든 개체에 추가하려고 'System.Collections.Generic.Dictionary`2를 입력 할'바가 '형식의 개체를 캐스팅 할 수 없습니다를 [선택 System.String , System.Object] '.

Dictionary<string, BagB>Dictionary<string, object> 번으로 변환 할 수없는 이유는 무엇입니까? 이 시나리오를 기반으로 내 항목을 추가하는 가장 좋은 방법은 무엇입니까? 아마 익명 메소드 ..? 나는 내 수업 바가과 BagB을 수정하지 않아도 선호

공지 사항 ...

감사합니다!

+0

왜 가방 B 대신 사전을 주조로 MyBagB 캐스트 :

약간의 Linq에 꽤 쉽게이 일을 무엇입니까? – zmbq

답변

2

, 그것은 당신이 자신의 메소드를 호출을 계속 사용할 필요가 공평 :

var addMethod = typeof(BagA).GetMethod("Add", new[] {typeof(string), typeof(BagB)}); 
addMethod.Invoke(MyBagA, new object[] {"123", MyBagB}); 
+0

그것이 조금 더 정교함에도 불구하고 내가 그 일을 끝내고 잘 작동하는 것이다. 당신의 도움을 주셔서 감사합니다! –

1

이것은 근본적으로 불가능합니다.

이렇게 할 수 있었다면 임의의 다른 유형을 추가 할 수 있습니다.

리플렉션을 사용하여 메소드를 호출해야합니다.

4

Dictionary<string, BagB>Dictionary<string, object>은 서로 다른 호환되지 않는 유형이므로 여기에서 캐스트를 수행 할 방법이 없습니다. Dictionary 대신에 값을 전송하는 것이 좋습니다.

MyBagA.Add("123", (BagB)MyBagB); 

IT는 Dictionary<TKey, TValue> 다음 다음 매우 악한 일이 일어날 수 캐스트 합법적 인 경우. 고려하십시오

Dictionary<string, BagB> map1 = ...; 
Dictionary<string, object> map2 = SomeEvilCast(map1); 
map2["foo"] = new object(); 

map1["foo"]에 액세스하려고하면 어떻게 될까요? 값의 유형은 object이지만 정적으로 BagB으로 입력됩니다. 당신이 당신의 개체를 만들 반사를 사용하기 때문에

+0

좋은 관찰 @JaredPar, 완벽한 감각을 만든다 –

1

할 수 있습니다 직접적으로 주조 또는 인스턴스에 제네릭 형식의 인스턴스로 변환 특정 제네릭 유형 매개 변수가있는 유형의 경우, 제네릭 유형이 해당 일반 유형 매개 변수에 대한 공변 (실제 선언 된 제네릭 유형의 기본 클래스의 제네릭으로 취급 될 수 있음)으로 구체적으로 정의되지 않은 한, 실제 유형의 기본 클래스 제네릭을 입력하십시오. 예를 들어, IEnumerable<string>은 문자열이 객체에서 파생되기 때문에 IEnumerable<object>으로 처리 될 수 있습니다. 문자열이 Char에서 파생되지 않았으므로 모든 문자열에 문자가 하나 뿐인 경우에도 IEnumerable<char>으로 처리 할 수 ​​없습니다.

일반 매개 변수에 out 키워드를 사용하여 C# 4.0에서 공 공성을 정의 할 수 있지만 IEnumerable과 달리 일반 IDictionary 인터페이스는 공변수로 지정되지 않습니다. 또한 사전은 IEnumerable이지만 일반 키/값 쌍의 IEnumerable이며 일반 KVP는 공변 적이 지 않으므로 KVP의 일반 매개 변수를 기본 유형으로 취급 할 수 없습니다.

새 형식의 새 사전을 만들고 이전 형식의 모든 값을 전송할 수 있습니다. 이러한 값이 참조 유형 인 경우 하나의 사전의 참조 유형 값의 하위 값을 변경하면 참조 자체를 변경하지 않는 한 MyClass의 새 인스턴스를 해당 값에 할당하여 해당 사전의 참조 유형 값의 하위 값을 다른 사전의 해당 값으로 변경합니다 키).

Dictionary<string, MyClass> MyStronglyTypedDictionary = 
    new Dictionary<string, MyClass>(); 
//populate MyStronglyTypedDictionary 

//a Dictionary<T1, T2> is an IEnumerable<KeyValuePair<T1, T2>> 
//so most basic Linq methods will work 
Dictionary<string, object> MyGeneralDictionary = 
    MyStronglyTypedDictionary.ToDictionary(kvp=>kvp.Key, kvp=>(object)(kvp.Value)); 

... 

//Now, changing a MyClass instance's data values in one Dictionary will 
//update the other Dictionary 
((MyClass)MyGeneralDictionary["Key1"]).MyProperty = "Something else"; 

if(MyStronglyTypedDictionary["Key1"].MyProperty == "Something else") 
{ 
    //the above is true; this code will execute 
} 

//But changing a MyClass reference to a completely new instance will 
//NOT change the original Dictionary 
MyGeneralDictionary["Key1"] = new MyClass{MyProperty = "Something new"}; 

if(MyStronglyTypedDictionary["Key1"].MyProperty == "Something else") 
{ 
    //the above is STILL true even though the instance under this key in the 
    //other Dictionary has a different value for the property, because 
    //the other dictionary now points to a different instance of MyClass; 
    //the instance that this Dictionary refers to never changed. 
} 
+0

올바르지 않습니다. 'List '는'stringList.Add (fileInfo);'를 호출 할 수 없기 때문에'List '으로 취급 될 수 없습니다. 'List '(또는'IEnumerable ')은'IEnumerable '로 취급 될 수 있습니다. 그래서 대답은 두 가지 문제가 있습니다 : (1)'List '은 공변 선언을하지 않습니다. (2) 클래스는 결코 공동 또는 반동으로 선언 될 수 없으며 오직 인터페이스와 델리게이트 만 선언 될 수 있습니다. – phoog