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,因为正如您所发现的,编译器不提供将实例化对象强制转换为多个接口的方法。您有两个选择:
创建一个新的界面iawesomecomparabling,它源自iThing,iawosey and sipableu003CT> ,让您的类型实现并施加。
通过以下方式调用 DoSomethingAwesome 反射。为此,您将 需要获取 MethodInfo DoSomethingAwesome泛型方法, 然后调用 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) );
不隶属于 StackOverflow