views:

980

answers:

3

This is what I need to do:

object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();

Can something like this be done?

+4  A: 

No, you cannot.

C# does not implement Duck typing.

Implement an interface and cast to it.

P. S. However there are attempts to do it. Look at Duck Typing Project.

Quassnoi
Yes you can. Look at GvS' answer :-)
Rune Grimstad
You still need to implement the interface (IConvertible in this case), and know the type being casted to in advance.
Quassnoi
I marked this answer as an accepted one since I used Quassnoi's advice and implemented an interface to cast to it, but GvS's and shuggycouk's answers are great too.
Marek Grzenkowicz
+4  A: 

You can use the Convert.ChangeType method.

object foo = GetFoo(); 
Type t = typeof(string);
string bar = (string)Convert.ChangeType(foo, t);
GvS
This is useful only if the object implements IConvertible
Quassnoi
I used string only as an example. The problem is I don't know the target type so I cannot perform this xyz bar = (xyz)Convert.Change... cast.
Marek Grzenkowicz
+1  A: 

Your original question was flawed in that you ask to treat a variable as a type which is not known at compile time but note that you have string defined on the left hand side when you declare your variable. C# as of 3.5 is statically typed.

Once dynamic is available you could do something like this:

dynamic foo = GetFoo();
foo.FunctionThatExistsInBarType();

For when you don't know what the type is but you know it will always support the instance method FunctionThatExistsInBarType();

for now you are forced to use reflection (or code gen which really amounts to much the same thing but more expensive up front and faster later).

// any of these can be determined at runtime
Type t = typeof(Bar);
string methodToCall = "FunctionThatExistsInBarType";
Type[] argumentTypes = new Type[0];
object[] arguments = new object[0];
object foo;
// invoke the method - 
// example ignores overloading and exception handling for brevity
// assumption: return type is void or you don't care about it
t.GetMethod(methodToCall, BindingFalgs.Public | BindingFlags.Instance)
    .Invoke(foo, arguments);
ShuggyCoUk
The string type was only an example (not a good one); I edited the code snippet, hope it's clearer now.
Marek Grzenkowicz
Right - for this (pre dynamic) you must use reflection. I will edit to take that into account
ShuggyCoUk