2010-06-14 4 views
3

BindingSource가 연결되거나 구성되는 항목의 유형을 얻고 싶습니다. BindingSource.DataSource 속성은 개체, 목록 또는 형식으로 설정할 수 있습니다. 그것이 유형이라면, 분명히 아직 묶여있는 항목이 없지만, 여전히 유형을 얻고 싶습니다. 목록의 경우 목록 유형이 아닌 항목 유형이 필요합니다.BindingSource에서 항목 유형을 가져올 수 있습니까?

현재이 문제를 해결하기 위해 만든 IListItemType 인터페이스를 구현하는 비즈니스 개체의 사용자 지정 목록 유형이 있습니다. 이제는 어떤 목록에서도 작동 할 수 있도록 좀 더 일반적인 방식으로이 작업을하고 싶습니다.

나는 이것을하기위한 좋은 방법에 대해 API 문서를 살펴 봤지만, 지금까지는 운이 없었습니다. 나는 뭔가를 놓치고 있는가, 아니면 내가 할 수 없거나하지 말아야 할 것인가?

+0

이 질문을 확인 - http://stackoverflow.com/questions/557340/c-generic-list-t-how-to-get-the-type-of-t –

+0

@Mikael : 그 질문에 ' t 관련이있는 것처럼 보입니다. 이 질문은 내부 *가 아닌 클래스의 * 외부 *를 다루는 것처럼 들립니다. –

답변

6

나는 최근 프레임 워크에서 이것을 실행했다. 이 클래스는 내가 찾던 모든 것을 갖추고 있습니다

System.Windows.Forms.ListBindingHelper.GetListItemType()와 GetListItemProperties()

.

2

목록의 "유형"을 얻는 완전히 일반적인 방법은 없습니다. 가장 일반적인 방법은 첫 번째 항목을 검토하는 것입니다,하지만 당신은 덜 특정 (즉, 컬렉션이 List<object> 될 수있는 모음에 보다 구체적인 유형의 개체를 가질 수있는이 잘못 될 수 있습니다 첫 번째 항목은 string 일 수 있으므로 List<string>이라고 추측 할 수 있습니다. 모든 요소가 동일한 유형 (확신 할 수 없으면 컬렉션의 제네릭 유형이나 다른 객체보다 구체적이지 않음을 의미)을 확인하면 첫 번째 항목을 검사하는 것이 가장 쉽습니다.

그 외에도 GetType을 사용하여 목록의 실제 유형을 검사하고 인터페이스를 점검 할 수 있습니다. 제발 컬렉션은 강력하게 타입이 지정되어 있으므로 IEnumerable<T>을 구현할 것이므로 해당 인터페이스에서 반복적으로 사용할 수있는 IEnumerable을 찾고 일반적인 유형 인수를 살펴볼 수 있습니다. 조금 이상하지 않지만 작동해야합니다.

TL; DR 버전

이보십시오. 당신이 list라는 변수에 저장된 목록을 .NET 3.5을 사용하고있는있는 가정 :

var listType = list.GetType().GetInterfaces() 
       .Where(t => t.Name == "IEnumerable" && t.IsGenericType) 
       .Select(t => t.GetGenericArguments()[0]).FirstOrDefault(); 

을만큼 목록이 IEnumerable<T> 구현으로, 이것은 당신에게 T을 줄 것이다. 그렇지 않은 경우 목록 유형은 object입니다.

+0

이 문제를 조사한 후에 GetItemProperties 메서드는 많은 도움이되지 않는 것처럼 보입니다. 속성 목록을 전달해야하며 항목에 존재하는 속성을 반환합니다. 그래서 이것은 속성 목록을 가져올 항목 유형을 얻는 방법에 대한 문제로 되돌아갑니다. 나는 그 시점에서 잘못된 추측을 제거하기 위해 질문을 편집 할 것입니다. –

+0

@Preston : 편집을보세요. –

+0

BindingSource에서 항목 유형을 직접 가져 오는 방법이 될 수 없다는 점을 충분히 생각하면 충분합니다. 내 범위를 제한하고 BindingSource가 일반 목록 형식을 갖거나 DataSource로 설정된 일반 목록 형식에서 파생 된 형식을 가져 와서 거기에서 이동할 것이라고 가정합니다. 또는 직접 바인딩 된 단일 항목 . 어쨌든 당신은 아이디어를 얻었고, 엣지 케이스의 범위를 벗어나면 문제는 사라집니다. 당신 생각을 가져 주셔서 감사합니다. –

1

이 대답은 보드에있다 그러나 다만 경우에 누군가가 여전히 해답을 찾고 있기 때문에 그것은 꽤되었습니다 ...

나는 비슷한 문제로 실행했습니다. 내 시나리오는 BindingSource.DataSource가 항상 IEnumerable에 바인딩되지만 목록에 항목이 없을 수도 있다는 것입니다. BindingSource에는 "itemType"이라는 private 인스턴스 멤버가 있습니다. 이 필드는 찾고자하는 바를 수행합니다. BindingSource가 목록에 바인딩되어있는 경우 목록의 요소 유형을 표시하거나 목록이없는 경우 BindingSource가 바인딩되는 개체의 유형을 표시합니다.

필드 값에 액세스하려면 좀 해키 반사 사용 : 많은 연구를하고하지 않고

FieldInfo fi = 
    typeof(BindingSource) 
    .GetField("itemType", BindingFlags.NonPublic | BindingFlags.Instance); 
Type myElementType = fi.GetValue(DataBinder.RestrictedDataBinding) as Type; 

을, 나는 가지 무엇인지는 innerList의 요소 유형을 보여주는하고있어, 그것은 아무튼 왜 가정 DataSource가리스트 형인지 아닌지는 중요하지 않습니다. 또한이 필드는 BindingSource (IQueryables 등 포함)에서 지원하는 모든 종류의 목록 요소 유형을 정확하게 표시한다고 가정합니다.

경고 :이 필드를 많이 테스트하지 않았으므로 올바른 요소 유형을 읽지 못하게하는 경우가 있는지 알 수 없습니다. 예를 들어, BindingSource의 DataSource 속성을 다시 설정하면 필드가 항상 정확하게 업데이트됩니까? DataSource 속성이 다른 elementType을 가진 목록으로 재설정되면 어떻게 될까요? 필자의 경우 이러한 예외 사항과 다른 예외 사항은 적용되지 않지만 테스트하려는 경우가 있습니다.

마지막으로 사적 영역을 해킹하기 위해 리플렉션을 사용하면 모든 종류의 끔찍한 원칙이 깨집니다. 그것을 명심하십시오. 또한 itemType 필드가 숨겨진 이유가있을 수 있습니다. 더 자세히 조사해야하는 경우 BindingSource 클래스의 코드를 공개적으로 사용할 수 있습니다.

관련 문제