C#:如何查找和创建满足多种类型约束的实例

C#:如何查找和创建满足多种类型约束的实例,c#,generics,reflection,activator,type-constraints,C#,Generics,Reflection,Activator,Type Constraints,假设我有一个具有多个类型约束的泛型方法,如下所示: public static void DoSomethingAwesome<T>(T thing) where T : IThing, IAwesome, IComparable<T> { ... } 但是,不能真正转换到多个接口。。。我究竟怎样才能解决这个问题?你可以说我现在在这里迷路了 标题有点长,有点复杂,因为我不知道该怎么称呼它,如果你可以的话,请改进一下。我猜你不能这么做是有原因的 var t

假设我有一个具有多个类型约束的泛型方法,如下所示:

public static void DoSomethingAwesome<T>(T thing)
    where T : IThing, IAwesome, IComparable<T>
{
    ...
}
但是,不能真正转换到多个接口。。。我究竟怎样才能解决这个问题?你可以说我现在在这里迷路了


标题有点长,有点复杂,因为我不知道该怎么称呼它,如果你可以的话,请改进一下。我猜你不能这么做是有原因的

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) );
//使用
静态布尔值(类型对象)
{
foreach(在thing.GetInterfaces()中键入interfaceType)
{
if(interfaceType.IsGenericType&&interfaceType.GetGenericTypeDefinition()==typeof(IComparable))
{
Type[]arguments=interfaceType.GetGenericArguments();
if(arguments.Length==1)
{
if(参数[0]==事物)
返回true;
}
}
}
返回false;
}
//这将返回兼容类型的可枚举项:
var types=assembly.GetTypes()。其中(t=>
类型的(i字符串)。IsAssignableFrom(t)&&
typeof(IAwesome).IsAssignableFrom(t)&&
ISI(t));

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

  • 创建一个新接口 有什么可比的 源于我的思想、勇敢和自信 我比较好,有你的 类型实现它,并强制转换为 那个

  • 通过调用DoSomethingAwesome 反射要做到这一点,你将 需要获取该方法的MethodInfo DoSomethingAwesome通用方法, 然后打电话 MethodInfo.MakeGenericMethod与 您的类型实现了这三个功能 接口

  • 第(2)项示例:


    但是,不处理IComparable约束,这是最棘手的。要实例化它们,请使用Activator.CreateInstance,就像您在问题中所做的那样。然后你有一个单独的问题,将它们传递给方法;我已经发布了一个讨论这个问题的答案。好吧,我可以,当然也会这样做,但那只会找到那些类。我在实例化它们时仍然会遇到困难。你能说一下你在实例化它们时遇到了什么样的困难吗?正如您所知,Activator.CreateInstance应该为您做到这一点;如果不是,你看到的错误是什么?还是将创建的实例强制转换为编译器将允许您传递给泛型方法的类型时出现问题?如果是的话,看看我的答案,看看可能的解决方案。就我所知,这也能帮助我找到那些类型。没有以我可以将它们发送到泛型方法的方式实例化它们。不过,
    IsComparable
    方法看起来非常有用,所以谢谢你:)对不起,我不想复制Reed和Loren关于如何找到合适类型的答案。我假设,使用其他答案,您可以找到合适的类型并实例化一个实例(使用Activator.CreateInstance)。然后将此类型传递给MakeGenericMethod,并传递要调用的实例。抱歉不够清晰。啊,我想我现在明白了。但是m是什么?应该是mgeneric吗?
    // 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) );
    
    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 });