假设我有一个具有多种类型约束的通用方法,这个:

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,因为正如您所发现的,编译器不提供将实例化对象强制转换为多个接口的方法。您有两个选择:

  1. 创建一个新的界面iawesomecomparabling,它源自iThing,iawosey and sipableu003CT> ,让您的类型实现并施加。

  2. 通过以下方式调用 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) );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top