SiberianGuy
SiberianGuy

Reputation: 25302

Instantiate generic type by reflection

Let's imagine I have instantiated generic type by Activator.CreateInstance. Is there any way to cast it to ISomeInterface if I don't have T in compile time (but I have it as Type instance)?

Here is a sample:

public static IPropertyAssertions<T> ShouldHave<T>(this T subject)
{
    var implementedInterfaces = subject.GetType().GetInterfaces();
    foreach (var interfaceType in implementedInterfaces)
    {
        if (!interfaceType.IsGenericType)
            continue;

        var genericType = interfaceType.GetGenericTypeDefinition();
        if (genericType == typeof(IEnumerable<>))
        {
            var genericTypeArg = genericType.GetGenericArguments()[0];

            var collectionPropertyAssertionsType = typeof (CollectionPropertyAssertions<>);

            Type makeme = collectionPropertyAssertionsType.MakeGenericType(genericTypeArg);

            return (IPropertyAssertions<ToDo: specify argument type here>) Activator.CreateInstance(makeme);
        }
    }

    ...
}

So I have extension method which can be called on IEnumerable<T>. In this case I would like to return not CollectionPropertyAssertions<IEnumerable<T>> but CollectionPropertyAssertions<T> where T is type of enumeration element.

Upvotes: 1

Views: 705

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500525

You won't be able to cast to it, no - you have to cast to a type which is known at compile-time... half the point is to then be able to use the specific members of that type.

Some scenarios you may want to consider:

  • If you want to call a generic method which needs an ISomeInterface<T> as a parameter, you could call this via reflection or use dynamic typing
  • If you want to call members which don't rely on T anyway, you might want to consider creating a non-generic base interface which ISomeInterface<T> extends - then you can just cast to the non-generic interface.

If that doesn't cover what you're trying to do, please provide more details.

EDIT: In this case you do know T because you're in a generic method - so you only need to cast to IPropertyAssertions<T>.

Upvotes: 5

Related Questions