2

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

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

标题有点长而复杂,因为我不知道该怎么称呼它,如果可以的话,请改进

4

3 回答 3

4

要添加到 Reed 和 Loren 关于寻找合适类型的答案,请注意您仍然无法通过强制转换调用 DoSomethingAwesome,因为正如您所发现的,编译器不提供将实例化对象强制转换为多个接口的方法。你有两个选择:

  1. 创建一个派生自 IThing、IAwesome 和 IComparable<T> 的新接口 IAwesomeComparableThing,让您的类型实现该接口并强制转换为该接口。

  2. 通过反射调用 DoSomethingAwesome。为此,您需要获取 DoSomethingAwesome 泛型方法的 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 });
于 2009-10-05T19:15:23.357 回答
0

我猜你不能这样做是有原因的

var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom))
于 2009-10-05T18:56:36.967 回答
0

您需要一种可以从所有约束中分配的类型。前两个很容易,但第三个有点棘手:

// 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) );
于 2009-10-05T19:03:55.970 回答