1

I'm trying to figure out how I can do something along the lines of

Type t = Type.GetType("fully qualified type name");
dynamic obj = foo as t

How do I do this? I was looking at Convert.ChangeType(), but that just returns an object and that's not what I want.

Lunyx
  • 3,164
  • 6
  • 30
  • 46
  • This is a similar question, but if you look at the marked answer's comments, it doesn't solve the question. It only solved it for whatever that other person was trying to do. – Lunyx Nov 21 '14 at 18:33
  • @Lynx, yup, My bad. that is why I decided to reopen it. – Habib Nov 21 '14 at 18:34
  • @Habib, I assume you are referring to http://stackoverflow.com/questions/972636/casting-a-variable-using-a-type-variable. This does seem to be a direct duplicate... If that question does not cover your use case, please post a more complete example. – Mitch Nov 21 '14 at 18:37
  • 3
    How is this useful in any situation? What would you do with `obj` now that you have cast it? – EkoostikMartin Nov 21 '14 at 18:38
  • What are you trying to do with that? What type is foo and is it actually a `t`? Or are you trying to have the runtime magically convert a representation in one type to some arbitrary other type? – Mike Zboray Nov 21 '14 at 18:39
  • @Mitch The difference is that `T` is (presumably) not known at compile-time – D Stanley Nov 21 '14 at 18:42
  • @DStanley, I agree, but if you do not have a compile-time known type, what is the problem with getting something of type `object`? – Mitch Nov 21 '14 at 18:43
  • @Mitch It's not a problem; I was just explaining why that question is not an exact duplicate – D Stanley Nov 21 '14 at 18:45
  • 1
    Sounds like a [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Please explain what you're trying to achieve. – Sriram Sakthivel Nov 21 '14 at 18:48
  • The `Type` is resolved at run time based on parameters supplied in a database table. So the type of t is defined in one of the classes, but not immediately known at compile time. – Lunyx Nov 21 '14 at 18:51
  • @Lunyx If you don't know what the type will be how are you going to call methods or access properties? – D Stanley Nov 21 '14 at 18:54
  • @Lunyx - okay so you know the type at runtime, and you casted the underlying type of the dynamic to it. Now what can you do with that? What was the point? – EkoostikMartin Nov 21 '14 at 18:55

2 Answers2

4

It seems like you are mixing disciplines, and I don't understand why. Either use reflection or dynamic typing, but using both makes little sense to me.

If you are doing something with types you control, have them implement an interface:

interface IModule
{
    string Name { get; }
}

class Module1 : IModule
{
    public string Name { get { return "Module 1"; } } 
}

public void PrintModuleName(string moduleType)
{
    Type tModule = Type.GetType("MyApp.Module1");
    IModule module = (IModule)Activator.CreateInstance(tModule);
    Console.WriteLine(module.Name); 
}

If you are working with types you don't control, use dynamic - no cast needed:

class Module1
{
    public string Name { get { return "Module 1"; } } 
}

public void PrintModuleName(string moduleType)
{
    Type tModule = Type.GetType("MyApp.Module1");
    dynamic module = Activator.CreateInstance(tModule);
    Console.WriteLine(module.Name); 
}

The only case where I could see the cast being necessary is for COM interop as a substitute for QueryInterface or if the type implements a cast which returns a new object.


Regarding your comment:

Since Convert.ChangeType() returns a type of object, wouldn't obj still resolve to a type of object during runtime? How does this differ from object obj = Convert.ChangeType(foo,t);? To my understanding, the dynamic keyword still uses the same type

Static typing specifies the most restricted type you are allowed to access in code. For example, you have a variable t typed as System.Type in the statement Type t = Type.GetType("foo");, but at runtime, GetType will return a value of type System.RuntimeType. Since System.RuntimeType inherits from System.Type, it is not a problem.

Similarly, everything* inherits from System.Object and can be stored in a variable typed as object. An example may be helpful:

System.Type t = Type.GetType("System.String");
Console.WriteLine("Runtime type of `t`:\t{0}", t.GetType().FullName);
// Prints "Runtime type of `t` is: System.RuntimeType"

System.String s = "foo";
Console.WriteLine("Runtime type of `s`:\t{0}", s.GetType().FullName);
// Prints "Runtime type of `s` is: System.String"

object o = s;
Console.WriteLine("Runtime type of `o`:\t{0}", o.GetType().FullName);
// Prints "Runtime type of `o` is: System.String"

Dynamic is syntactic sugar for Reflection, and therefore does not exist as a separate type. So:

string s = "foo";
Console.WriteLine("Runtime type of `s`:\t{0}", s.GetType().FullName);
// Prints "Runtime type of `s` is: System.String"

dynamic d = s;
Console.WriteLine("Runtime type of `d:\t{0}", d.GetType().FullName);
// Also prints "Runtime type of `d` is: System.String"

Is the same as:

string s = "foo";
Console.WriteLine("Runtime type of `s`:\t{0}", s.GetType().FullName);

Type typeOfS = s.GetType();
object resultOfGetType = typeOfS.GetMethod("GetType").Invoke(s, null);
Type typeOfResultOfGetType = resultOfGetType.GetType();
object resultOfFullName = typeOfResultOfGetType.GetProperty("FullName").GetValue(resultOfGetType);

Console.WriteLine("Runtime type of `d:\t{0}", resultOfFullName);

The C# just generates all of this code** at compile-time.

*: well... most everything
**: well... not exactly this code

Mitch
  • 21,223
  • 6
  • 63
  • 86
0

You can't use as since it requires the type to be known at compile-time. Since you're already using dynamic why not just do:

dynamic obj = Convert.ChangeType(foo, t);

The return type of the Convert.ChangeType method is object, but the actual type of the underlying object will be t, so you can still use it's methods and properties dynamically.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Since `Convert.ChangeType()` returns a type of object, wouldn't obj still resolve to a type of object during runtime? How does this differ from `object obj = Convert.ChangeType(foo,t);`? To my understanding, the dynamic keyword still uses the same type. – Lunyx Nov 21 '14 at 18:46
  • @Lunyx dynamic only turns off compile time type checking. `obj` is at runtime whatever type `ChangeType` returned in both cases. – Mike Zboray Nov 21 '14 at 18:49
  • @Lunyx No, otherwise `ChangeType` would be pointless (you'd just get a vanilla object back). The _design time_ type of the object will be `object`, but the _actual_ type would be `t` (meaning you could use reflection or `dynamic` to get to the members of type `t`). – D Stanley Nov 21 '14 at 18:50
  • If that's the case, then I've been misunderstanding what actually happens when the dynamic keyword is used. I'll give this a try and see what happens. – Lunyx Nov 21 '14 at 18:52
  • @Lunyx to your second question, a `dynamic` is NOT just an `object` - the actual object will have a runtime type; it just defers binding of properties and methods to run-time (which was previously only possible through reflection). – D Stanley Nov 21 '14 at 18:53
  • @DStanley I was thinking that in this specific case, dynamic would resolve to object since the return type of Convert.ChangeType is of type object. – Lunyx Nov 21 '14 at 19:02
  • No, that's just the _design-time_ type - it can in reality be any type. Just list iterating an `ArrayList` returns `object`s, but the _actual_ type is probably something else. If you looked at it in the debugger you would see that it;s not _just_ an `object`. – D Stanley Nov 21 '14 at 19:14
  • This doesn't seem to work on everything. The object must implement IConvertible interface. – Lunyx Nov 21 '14 at 20:16
  • @Lunyx If you're not actually converting the type (meaning the object is _already_ of that type) you can just do `dynamic obj = t`. – D Stanley Nov 21 '14 at 23:02