简体   繁体   English

如何使用C#和Reflection获取实现类类型而不是接口类型

[英]How to use C# and Reflection to get Implemented Class type not the Interface type

UPDATE: My "problem" was due to a bad assumption about the class I was using reflection upon. 更新:我的“问题”是由于对我正在使用反射的类的错误假设所致。 My question below is nonsensical as it doesn't act that way. 我下面的问题是荒谬的,因为它不会那样做。 But I am leaving it here in case the code snippet is useful. 但是,如果代码段有用,我将其保留在此处。

I am using reflection to generate viewmodels off of a compiled class that resides in a separate assembly. 我正在使用反射来生成驻留在单独程序集中的已编译类的视图模型。 Most everything is working except the types I get back from the compiled assembly shows an interface instead of the class that is the concrete implementation of the interface. 除了我从编译后的程序集返回的类型显示了一个接口而不是作为该接口的具体实现的类之外,大多数其他东西都在工作。

For example, in the compiled assembly I define a property like: 例如,在已编译的程序集中,我定义了如下属性:

    public List<String> strings { get; set; }

Using reflection, I have been able to generate a corresponding property (and complete class) that looks like this: 使用反射,我已经能够生成如下所示的相应属性(和完整的类):

    public ICollection<String> strings { get; set; }

I get the types doing this (severely snipped for brevity): 我得到执行此操作的类型(为简洁起见严重被剪掉):

    Type value = <...some passed in type...>
    String types = String.Join(",", value.GetGenericArguments().Select(t => t.Name).ToArray());

    String.Format("{0}<{1}>", value.GetGenericTypeDefinition(), types);

Is there any way using the Type object to determine what concrete implementation was used for the interface returned? 是否可以使用Type对象确定返回的接口使用了哪种具体实现? I am guessing no but thought I would ask. 我猜不,但我想问。

If there is not a way, I am thinking of using a "most likely implementation" look up for a given interface (ie you pass in "ICollection", I translate that into a concrete "List") unless there is a better suggestion??? 如果没有办法,除非有更好的建议,否则我正在考虑使用“最可能的实现”查找给定的接口(即,您传递“ ICollection”,将其转换为具体的“ List”)。 ??

A "perfect" solution isn't necessarily required as this is used to generate Controllers, Views, and ViewModels (with automapper and Kendo UI) using T4 templates. 不一定需要“完美”的解决方案,因为该解决方案用于使用T4模板生成Controllers,Views和ViewModels(带有自动映射器和Kendo UI)。 So if there are a few things to clean up, that is fine. 因此,如果有几件事需要清理,那就很好。 So any suggestions that get me close are welcome. 因此,欢迎您提出任何让我接近的建议。

Well, i played with reflection a little bit and here what I came with: 好吧,我玩了一点思考,这是我带来的:

    //Initial list with ints
    var items = new List<int> {1, 2, 3, 4, 5};
    //ICollection<int> reference
    var collectionOfItems = (ICollection<int>) items;

    //...

    //First of, get collection Type object
    var collectionType = collectionOfItems.GetType();
    //Next, let's grab generic arguments
    var genericArguments = collectionType.GetGenericArguments();

    //For each generic candidate type we need to construct it with collection's generic arguments
    var candidate = typeof(List<>).MakeGenericType(genericArguments);

    //Perform check
    if (collectionType.IsAssignableFrom(candidate))
        Console.WriteLine("Can be casted to {0}", candidate);
    else
        Console.WriteLine("Cannot be cated to {0}", candidate);

Yes, it's possible with reflection , but you need to check against a lot of possible types (some not BCL type can also implement ICollection ). 是的,可以通过反射实现,但是您需要检查很多可能的类型(有些不是BCL类型也可以实现ICollection )。 Better just declare properties with concrete types 最好只用具体类型声明属性

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

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