IEnumerable을 IEnumerable로 변환/캐스트
IEnumerable 형식의 속성이 있고 LINQ를 사용하여 매개 변수로 작업하려는 클래스(웹 컨트롤)가 있습니다.
컴파일 타임에 유형을 모르는 IEnumerable<T>에 대한 리플렉션을 통해 캐스트/변환/호출하는 방법이 있습니까?
Method void (IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
var type = enumerator.Current.GetType();
Method2<type>(source); // this doesn't work! I know!
}
}
void Method2<T>(IEnumerable<T> source) {}
당신은 Method2
그것이 어떤 유형이 되는지 정말로 신경쓰나요? 그렇지 않은 경우 다음을 호출할 수 있습니다 Cast<object>()
.
void Method (IEnumerable source)
{
Method2(source.Cast<object>());
}
올바른 유형을 확실히 가져와야 하는 경우 리플렉션을 사용해야 합니다.
다음과 같은 것:
MethodInfo method = typeof(MyType).GetMethod("Method2");
MethodInfo generic = method.MakeGenericMethod(type);
generic.Invoke(this, new object[] {source});
소스가 아닌 경우, 특히 ... 이상적인 생각이 아니다 정확히 는 IEnumerable<type>
다음 호출이 실패합니다. 예를 들어, 첫 번째 요소가 문자열이지만 소스가 List<object>
이면 문제가 발생합니다.
사용하기 위해 코드를 리팩토링하고 싶을 것입니다. IEnumerable.Cast<T>
다음과 같이 사용하십시오.
IEnumerable mySet = GetData();
var query = from x in mySet.Cast<int>()
where x > 2
select x;
.NET 4를 사용하면 메서드에 전달 source
하기 dynamic
전에 캐스트할 수 있습니다 . 이렇게 하면 추한 리플렉션 코드 없이 런타임에 올바른 일반 오버로드가 해결됩니다.
void Method(IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
Method2((dynamic)source);
}
}
Jon의 두 번째 솔루션과 마찬가지로 소스가 실제로 IEnumerable<T>
. 일반 경우 다음 솔루션에서와 같이 IEnumerable
올바른 IEnumerable<T>
유형으로 변환하는 다른 메서드를 만들어야 합니다.
IEnumerable<T> Convert<T>(IEnumerable source, T firstItem)
{
// Note: firstItem parameter is unused and is just for resolving type of T
foreach(var item in source)
{
yield return (T)item;
}
}
void Method(IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
dynamic firstItem = enumerator.Current;
dynamic typedEnumerable = Convert(source, firstItem);
Method2(typedEnumerable);
}
}
이것은 몇 년 후이지만 List<Object>
문제를 해결했습니다 .
void Method(IEnumerable source)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
MethodInfo method = typeof(MyClass).GetMethod("Method2");
MethodInfo generic;
Type type = enumerator.Current.GetType();
bool sameType = true;
while (enumerator.MoveNext())
{
if (enumerator.Current.GetType() != type)
{
sameType = false;
break;
}
}
if (sameType)
generic = method.MakeGenericMethod(type);
else
generic = method.MakeGenericMethod(typeof(object));
generic.Invoke(this, new object[] { source });
}
}
참조URL : https://stackoverflow.com/questions/812673/convert-cast-ienumerable-to-ienumerablet
'IT이야기' 카테고리의 다른 글
TypeScript - 올바른 버전의 setTimeout 사용(노드 대 창) (0) | 2021.10.07 |
---|---|
헤더에 대한 "../include/header.h"와 같은 상대 경로의 이점 (0) | 2021.10.06 |
div를 페이지(화면 아님) 높이의 100%로 만드는 방법 (0) | 2021.10.06 |
사전의 크기를 제한하는 방법 (0) | 2021.10.06 |
cmd에서 stderr로 메시지를 보내려면.. (0) | 2021.10.05 |