繁体   English   中英

.NET通用类型-查找最特定的类型

[英].NET generic types - finding most specific type

是否有确定“最佳”类型以实例化以满足请求的好的算法?

例如说我有以下课程:

public interface ISometype<T> {}
public class SomeTypeImpl<T>:ISometype<T> {}
public class SomeSpecificTypeImpl<T>:ISometype<T> where T: ISpecificSpecifier {}
public interface ISpecificSpecifier { } 

假设调用者想要此接口的最佳实现类型。 我可以像这样实现这种特殊的方法:

public Type GetBestImplementationType(Type genericParam) {
    try {
        return typeof(SomeSpecificTypeImpl<>).MakeGenericType(genericParam);
    } catch(ArgumentException) {}
    return typeof(SomeTypeImpl<>).MakeGenericType(genericParam);
}

尽管此实现适用于这种特殊情况,但我更关注归纳法,在归纳法中可能有多个潜在的特定实现和多个通用参数:

public Type GetBestImplementationType(Type[] genericParams, Type[] potentialTypes) {
    foreach(var t in potentialTypes) {
        try {
            return t.MakeGenericType(genericParams);
        } catch(ArgumentException) {}
    }
    throw new Exception("unable to find specific implementation type");
}

如果从最高到最不特定的顺序提供了potentialTypes数组,这应该可以工作。 因此,对于答案,可以使用实现此方法的算法(或足够类似的东西)或实现我可以在此方法中使用的排序的算法。
[警告:代码未经测试,可能存在语法/逻辑错误]

我认为这样做的唯一方法是迭代所有程序集中的所有类,这可能会很慢。

这是asp.net MVC如何搜索项目中的所有控制器的方法:

    private static List<Type> GetAllControllerTypes(IBuildManager buildManager) {
        // Go through all assemblies referenced by the application and search for
        // controllers and controller factories.
        List<Type> controllerTypes = new List<Type>();
        ICollection assemblies = buildManager.GetReferencedAssemblies();
        foreach (Assembly assembly in assemblies) {
            Type[] typesInAsm;
            try {
                typesInAsm = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex) {
                typesInAsm = ex.Types;
            }
            controllerTypes.AddRange(typesInAsm.Where(IsControllerType));
        }
        return controllerTypes;
    }

在您的情况下,您可以将代码重做为类似的内容:

    private static List<Type> GetAllSubtypesOf(Type anInterface) {
        List<Type> types = new List<Type>();
        ICollection assemblies = buildManager.GetReferencedAssemblies();
        foreach (Assembly assembly in assemblies) {
            Type[] typesInAsm;
            try {
                typesInAsm = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex) {
                typesInAsm = ex.Types;
            }
            types.AddRange(typesInAsm.Where(t => anInterface.IsAssignableFrom(t)));
        }
        return types;
    }

请注意,因为遍历所有程序集的效率非常低,因为asp.net MVC只能执行一次并缓存结果。

看起来:

  1. 除了尝试创建类型并捕获异常之外,没有其他更好的方法来确定是否满足泛型类型的约束(可以这样做,但是看起来至少需要花费异常方法的时间,而且要复杂得多) 。
  2. 由于#1,[从计算上]很难将一组类型从最具体到最不具体排序。 相反,在代码中,我的解决方案是显式告诉我的容器如何对类型进行排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM