如何在运行时反映接口类型<t>

我有多个数据点和每个相关的数据处理器。


public interface IDataPointProcessor<T> where T : DataPointInputBase

{

    DataPointOutputBase GetOutput(T input);

}

我从文件加载数据点列表,并希望使用其单个关联处理器处理它们。


foreach (DataPointInputBase item in input.DataPoints)

{

    //assuming item coming in is of type 'X' how do I get correct processor

    var type = typeof(IDataPointProcessor<X>);

    var types = AppDomain.CurrentDomain.GetAssemblies()

                .SelectMany(s => s.GetTypes())

                .Where(p => type.IsAssignableFrom(p) && !p.IsAbstract);


    IDataPointProcessor<X> matchedType = ??


}

我如何解决“X”以便我可以实例化它并处理输入?


更新 #1 结合下面来自 Slava 和 Lucky 的答案,我得到以下结果,但它引发了一个异常——“对象与目标类型不匹配。” 即使在调试器中看起来一切都很好。是否可以转换为 IDataPointProcessor<> 并干净地调用接口方法,即: instance.GetOutput(item);


foreach (DataPointInputBase item in input.DataPoints)

{

    Type typeGenArg = item.GetType();


    Type typeInterfaceGen = typeof(IDataPointProcessor<>).MakeGenericType(typeGenArg);


    Type type = AppDomain.CurrentDomain.GetAssemblies()

        .SelectMany(x => x.GetTypes())

        .Where(x => typeInterfaceGen.IsAssignableFrom(x) && !x.IsAbstract)

        .FirstOrDefault();


    Type genericType = typeof(IDataPointProcessor<>);


    Type dependedGenericType = genericType.MakeGenericType(typeof(DataPointInputBase));


    var method = dependedGenericType.GetMethod("GetOutput");

    var instance = Activator.CreateInstance(type);

    //currently throws:System.Reflection.TargetException: 'Object does not match target type.'

    var result = method.Invoke(instance, new object[] { item });

    //Ideally I want to do this and avoid the magic strings etc

    //var temp_output = instance.GetOutput(item);

}


慕尼黑8549860
浏览 187回答 2
2回答

Smart猫小萌

首先,你应该像这样使你的界面协变。public interface IDataPointProcessor<in T> where T : DataPointInputBase{&nbsp; &nbsp; DataPointOutputBase GetOutput(T input);}您应该检索由 实现的类型IDataPointProcessor<>,然后您应该创建检索类型的实例并调用泛型类型的方法。Type genericType = typeof(IDataPointProcessor<>);var types = AppDomain.CurrentDomain.GetAssemblies()&nbsp; &nbsp; .SelectMany(s => s.GetTypes())&nbsp; &nbsp; .Where(p => genericType.IsAssignableFrom(p) && !p.IsAbstract).ToList();var dependedGenericType = genericType.MakeGenericType(typeof(DataPointInputBase));var method = dependedGenericType.GetMethod("GetOutput");var instance = Activator.CreateInstance(types[0]);method.Invoke(instance, new object[] { new DataPointInputBase() });
打开App,查看更多内容
随时随地看视频慕课网APP