2013-03-19 1 views
3

저는 Value Injecters를 사용하여 LoopValueInjection을 사용하여 한 유형에서 다른 유형으로 매핑하고 일부 맞춤 로직으로 SetValue (오브젝트 v) 메소드를 재정의했습니다. HashSet이 전달 될 때이를 감지하고 HashSet을 통과하여 각 항목에 메소드를 적용하여 정리를 시도합니다. 매개 변수가 객체 일 뿐이므로 HashSet에 항목의 유형이 무엇인지 알지 못하기 때문에 내가 겪고있는 문제가 있습니다. 예를 들어, HashSet 또는 HashSet 일 수 있습니다.HashSet <T>이 객체로 제공되고 T가 무엇이든간에 루프하는 방법은 무엇입니까?

현재 현재 가지고있는 코드는 있지만 InvalidCastException이 발생합니다.

protected override object SetValue(object v) 
    { 
     if (type.Name == "HashSet`1") 
     { 
      var genericType = type.GetGenericArguments()[0]; 

      // this line throws the InvalidCastException 
      var cleanHashSet = (HashSet<object>)Activator.CreateInstance(type); 

      foreach (var item in (HashSet<object>)v) // I'm sure this cast will throw as well 
      { 
       cleanHashSet.Add(Clean(item)); 
      } 

      return cleanHashSet; 
     } 

     return base.SetValue(v); 
    } 

나는 주요 질문은 어떻게 추측 할 수 나는 그것이 실제로 어떤 종류의 HashSet의입니다 결정되면 객체로 전달되는 HashSet의를 통해 I 루프? 또한 특정 유형의 새 빈 HashSet을 만들어야하므로 각 항목을 정리할 수 있다고 생각하고 있습니다.

답변

6

. .NET에서만 인터페이스와 대리인 유형은 공동 및 대조 유형이 될 수 있습니다. 따라서 HashSet<SomeType>HashSet<object>으로 전송할 수 없습니다.

당신은 당신이 반사와 Add 메소드를 호출 할 필요가 dynamic 키워드를 사용하지 않을 경우 IEnumerable 인터페이스

dynamic cleanHashSet = Activator.CreateInstance(type); 
foreach (object item in (IEnumerable)v) 
{ 
    cleanHashSet.Add(Clean(item)); 
} 

의 제네릭이 아닌 버전으로 v 캐스팅 할

object cleanHashSet = Activator.CreateInstance(type); 
var method = type.GetMethod("Add"); 
foreach (object item in (IEnumerable)v) 
{ 
    method.Invoke(cleanHashSet, new object[] { Clean(item) }); 
} 
+0

정확히 내가 필요로하는 것, 동적에 대해 생각하지 않았습니다. 감사! –

0

사용 :

bool isHashSet = typeof(HashSet<object>).IsAssignableFrom(type); 

또는

object x = ... 
HashSet<object> hs = x as HashSet<object>; 
if (hs != null) 
{ 
    // use hs 
} 

당신이 정말로 <T> 후 지정된 object 대신 사용하는 경우

.

HashSet<T>implementsICollection<T>


, IEnumerabel<T>, IEnumerable. 당신이 T을 안다면 열거하고 추가 할 수 있다는 것을 의미합니다. 그렇지 않으면 열거 형을 열거하십시오.

+0

@hazzik : 감사합니다. 결정된. 그것이 가능한 한. – abatishchev