tags:

views:

394

answers:

1

The following program works correctly. However, I would like to change it to not use InvokeMember. I would like to be able to cast the return value from CreateInstance into GenericBase and call the Foo method directly. In this code sample I know that the type is Derived. However, in my actual code, all I know is that the type is derived from GenericBase. All my attempts to cast an object into a GenericBase fail to compile. C# insists that I supply the type parameter when I use GenericType in a cast.

Is this possible?

using System;
using System.Collections.Generic;
using System.Text;

namespace GenericTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(Derived);
            object o = Activator.CreateInstance(t);
            t.InvokeMember("Foo", System.Reflection.BindingFlags.InvokeMethod, null, o, new object[] { "Bar" });
        }
    }

    class GenericBase<T>
    {
        public void Foo(string s)
        {
            Console.WriteLine(s);
        }
    }

    class Derived : GenericBase<int>
    {
    }
}
+2  A: 

A priori, you know nothing about the common features that might exist between GenericBase<Bar> and GenericBase<Baz>. It's possible they have nothing in common. So without knowing the type of the parent generic class, you actually don't know anything useful at all about the object.

Now, on the other hand, it's clear that what you're saying in this particular example is that there is something in common between GenericBase<Bar> and GenericBase<Baz> -- they both implement the non-generic void Foo(string s). So to be able to do something useful with your object, you need to formalize this behavior; put Foo into a non-generic IFoo interface, and have GenericBase<T> implement the interface. Then you can cast your object to an IFoo, and call Foo.

mquander
I thought of interfaces, but didn't mention this is my question. It might be the most elegant solution.
Mike Thompson
It is. You might be interested in this Eric Lippert blog entry on the topic of generic "mumble types" (his coined word for references to generic types where you don't care about the generic part of the type right now:) http://blogs.msdn.com/ericlippert/archive/2008/05/19/a-generic-constraint-question.aspx
mquander
In my real code the Foo method is generic (it instantiates a T object -- it does not have any parameters of T or return a T). So the interface technique works even though Foo is generic.
Mike Thompson