C#: 여러 유형 제약 조건을 충족하는 인스턴스를 찾고 작성하는 방법
-
19-09-2019 - |
문제
여러 유형의 제약 조건이있는 일반적인 방법이 있다고 가정 해 봅시다.
public static void DoSomethingAwesome<T>(T thing)
where T : IThing, IAwesome, IComparable<T>
{
...
}
이제 .... 반사를 사용하여 거기에서 보낼 수있는 것을 어떻게 만들 수 있습니까?
그것이 단 하나의 제약 일 뿐이라면 다음과 같이 할 수 있다는 것을 알고 있습니다.
var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom)
foreach(var t in types)
DoSomethingAwesome((IThing) Activator.CreateInstance(t));
그러나 실제로 여러 인터페이스로 캐스트 할 수 없습니다 ... 지구상에서 어떻게 해결할 수 있습니까? 당신은 내가 지금 여기서 거의 길을 잃었다 고 말할 수 있습니다 : P
내가 이것을 무엇이라고 부를지 잘 모르기 때문에 제목은 길고 복잡해졌습니다. 가능하면 개선하십시오.
해결책
적절한 유형을 찾는 것에 대한 Reed와 Loren의 답변에 추가하려면 캐스팅을 통해 Dosomethingawesome을 호출 할 수 없습니다. 컴파일러는 인스턴스화 된 객체를 여러 인터페이스에 캐스팅하는 방법을 제공하지 않기 때문입니다. 두 가지 옵션이 있습니다.
Ithing, iawesome 및 Icomparyable에서 파생 된 새로운 인터페이스 iawesomecomecomepablathing을 만듭니다.u003CT> , 당신의 유형이 그것을 구현하고 그것을 캐스팅하도록하십시오.
반사를 통해 dosomethingawesome을 호출하십시오. 이렇게하려면 dosomethingawesome generic 메소드의 MethodInfo를 가져 와서 MethodInfo.MakeGenericMethod를 호출하여 세 인터페이스를 모두 구현하는 유형으로 호출해야합니다.
(2)의 예 :
Type type = sometype; // For example found using reeds method
MethodInfo mgeneric = typeof(Awesomeiser).GetMethod("DoSomethingAwesome");
MethodInfo mspecific = mgeneric.MakeGenericMethod(new [] { type });
mspecific.Invoke(null, new [] { type });
다른 팁
당신이 할 수없는 이유가 있다고 생각합니다
var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom))
모든 제약 조건에서 할당 할 수있는 유형이 필요합니다. 처음 두 개는 쉽지만 세 번째는 약간 까다 롭습니다.
// Using
static bool IsIComparable(Type thing)
{
foreach (Type interfaceType in thing.GetInterfaces())
{
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IComparable<>))
{
Type[] arguments = interfaceType.GetGenericArguments();
if (arguments.Length == 1)
{
if (arguments[0] == thing)
return true;
}
}
}
return false;
}
// This returns an enumerable of compatible types:
var types = assembly.GetTypes().Where( t =>
typeof(IThing).IsAssignableFrom(t) &&
typeof(IAwesome).IsAssignableFrom(t) &&
IsIComparable(t) );