2

Now, before you all rush in to tell me that question has been answered elsewhere here, for example or here, let me say it's only been partially answered, at least as far as I can see.

I have a variable of type Type and I want to create an instance of the type that t represents, so I call something like...

var inst = Activator.CreateInstance(t);

However, inst is on object and I want it to be of type t. None of the following are legal:

t inst = Activator.CreateInstance(t);
var inst = (t)Activator.CreateInstance(t);
var inst = Activator.CreateInstance(t) as t;

How do I do this? How do I get inst to be the type that I want at compile-time?

Community
  • 1
  • 1
Stuart Hemming
  • 1,553
  • 2
  • 21
  • 44
  • " How do I get inst to be the type that I want at compile-time?" - for what purpose? what are you actually trying *to do* with this? if you tell us what you are trying to achieve, I suspect we can advise on an appropriate way to do it. – Marc Gravell Feb 03 '15 at 09:21
  • @MarcGravell, I need to be able to pass `inst` as a typed parameter to another method. – Stuart Hemming Feb 03 '15 at 09:22
  • a single method? or a series of overloads with different typed parameters? if it is a single method: just cast it - `Foo(123, "abc", (SomeType)inst);`; if it is series of overloads: `dynamic` might help - but is a hack – Marc Gravell Feb 03 '15 at 09:23
  • Essentially, it would be one of a number of different methods based on the type itself. – Stuart Hemming Feb 03 '15 at 09:24
  • 1
    then either *reflection* (manually select and invoke the method), or `dynamic`. The latter is basically an automated way of doing the former. `Foo(123, "abc", (dynamic)inst);` will call the most appropriate method it can find (or error if it can't find an appropriate one) – Marc Gravell Feb 03 '15 at 09:26
  • @MarcGravell, thanks. I'll go and do some research in to `dynamic`. – Stuart Hemming Feb 03 '15 at 09:27
  • @MarcGravell, if you want to copy your question as an answer I'll accept it as such. – Stuart Hemming Feb 03 '15 at 09:28
  • edited (with more detail and context, etc) – Marc Gravell Feb 03 '15 at 09:35

1 Answers1

3

That simply isn't possible. The compiler is static typed (except for when it isn't ;p). t is a variable. variable != static. What you want to do isn't possible.

One option here is generics, but that still gets it you as a <T>, which doesn't help any if <T> still only knows about the same methods as object. Another option is dynamic; that means inst.Foo(); will work - but only at runtime, and only if the type really does have a Foo() method; importantly, the compiler still won't know about t's methods at compile-time.


From the comments, it seems that the intended usage here is for method overload resolution; dynamic can help with that - for example:

Foo(Customer cust) {...}
Foo(Order order) {...}
Foo(Region region) {...}

object inst = Activator.CreateInstance(t); // t probably one of the above types
...
Foo((dynamic)inst);

will try to invoke the most appropriate Foo overload based on the runtime type of inst, with per-type cache optimizations etc. It is a bit of a hack, but it works, and is easier and cleaner than checking manually (and thanks to the strategy cache, often more efficient too).

If the only thing you are doing with inst is passing it onwards, you could make inst itself dynamic:

dynamic inst = Activator.CreateInstance(t);
Foo(inst);

Note that you should generally be a little cautious of this, however, as once a variable is dynamic, all access to it is via the dynamic API - even a call to a method that takes an object parameter (such as string.Format) would be routed via the runtime rather than the compiler (unless of course you explicitly cast it back to object or similar).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900