如何投射到给定的类型?

时间:2014-11-21 18:31:19

标签: c# reflection casting

试图找出我可以按照

的方式做些什么
Type t = Type.GetType("fully qualified type name");
dynamic obj = foo as t

我该怎么做?我看着Convert.ChangeType(),但这只是返回一个对象,而不是我想要的。

2 个答案:

答案 0 :(得分:4)

看起来你正在混合学科,我不明白为什么。使用反射或动态类型,但使用两者对我来说没什么意义。

如果您正在使用您控制的类型执行某些操作,请让它们实现接口:

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); 
}

如果您使用的是您无法控制的类型,请使用dynamic - 无需投射:

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); 
}

唯一可以看到转换是必要的情况是COM interop作为QueryInterface的替代,或者类型实现了返回新对象的转换。

<小时/> 关于你的评论:

  

由于Convert.ChangeType()返回一种对象,因此obj仍然不会   在运行时解析为一种对象?这有什么不同   object obj = Convert.ChangeType(foo,t);?据我所知,   dynamic关键字仍然使用相同的类型

静态类型指定允许您在代码中访问的最受限制的类型。例如,您在语句t中键入System.Type变量为Type t = Type.GetType("foo");,但在运行时,GetType将返回类型System.RuntimeType的值。由于System.RuntimeType继承自System.Type,因此不存在问题。

同样,所有*都继承自System.Object,并且可以存储在类型为object的变量中。一个例子可能会有所帮助:

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是Reflection的语法糖,因此不作为单独的类型存在。所以:

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"

与:

相同
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);

C#只是在编译时生成所有这些代码**。

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

答案 1 :(得分:0)

您无法使用as,因为它需要在编译时知道类型。由于您已经在使用dynamic,为什么不这样做:

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

Convert.ChangeType方法的返回类型为object,但基础对象的实际类型为t,因此您仍然可以使用它的方法和属性动态。