ZeroBugBounce
ZeroBugBounce

Reputation: 3670

How can I use reflection to find which open generic argument on an open generic type implements a generic interface?

In my code, I will be getting a type object representing an open, generic class that implements (at least) 2 open generic interfaces. At least one of these interfaces (IGiveOneValue in the example) is known by me. Here's a complete, working example:

using System;
namespace ConsoleApplication22
{
    interface IGiveOneValue<T>
    {
        T Value { get; }
    }

    interface IGiveAnother<T>
    {
        T Value { get; }
    }

    class ValueImplementation<T1, T2> : IGiveOneValue<T1>, IGiveAnother<T2>
    {
        public ValueImplementation(T1 value1, T2 value2)
        {
            v1 = value1;
            v2 = value2;
        }

        T1 v1;
        T2 v2;

        T1 IGiveOneValue<T1>.Value { get { return v1; } }
        T2 IGiveAnother<T2>.Value { get { return v2; } }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var genericArguments = typeof(ValueImplementation<,>).GetGenericArguments();
            // genericArguments.Length == 2
            // how can I tell which argument will fulfill IGiveOneValue<T>?
            // assuming they could be implemented in any order

            // these parameters might be in the wrong order:
            var closedType = typeof(ValueImplementation<,>).MakeGenericType(new[] { typeof(int), typeof(string)});
            var instance = Activator.CreateInstance(closedType, 1, "2");
        }
    }
}

How can I use reflection to determine which of the open generic arguments in the ValueImplementation<,> class corresponds to IGiveOneValue's member, so I can pass in a specific type to it in the MakeGenericType method?

Upvotes: 0

Views: 286

Answers (1)

Simon Whitehead
Simon Whitehead

Reputation: 65079

The GetInterfaces method will grab the interfaces for the type, and it also allows you to use GetGenericArguments. So if you wanted to know which interface the type implements uses which type constraint, you could try:

var genericArguments = typeof(ValueImplementation<,>).GetGenericArguments();
var implementedInterfaces = typeof(ValueImplementation<,>).GetInterfaces();

foreach (Type _interface in implementedInterfaces) {
    for (int i = 0; i < genericArguments.Count(); i++) {
        if (_interface.GetGenericArguments().Contains(genericArguments[i])) {
            Console.WriteLine("Interface {0} implements T{1}", _interface.Name, i + 1);
        }
    }
}

Hopefully I've understood your question and that this provides some guidance.

Upvotes: 2

Related Questions