简体   繁体   中英

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? 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???

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. 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 ). Better just declare properties with concrete types

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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