使用对象类型的字符串名称在c#中键入cast

nob*_*ody 5 c# reflection types casting

我有以下代码,应该很容易通过

public class Foo
{
    public void FooHasAMethod()
    {
        Console.WriteLine("it is me, foo!!!");
    }
}

public class Bar
{
    public Foo FooProperty { get; set; }
}

public class FooBar
{
    public static void Main()
    {
        Bar bar = new Bar{ FooProperty = new Foo() };
        CallPropertyByName(bar, "Foo");
    }

    public static void CallPropertyByName(Bar bar, string propertyName)
    {
        PropertyInfo pi = bar.GetType().GetProperty(propertyName + "Property");
        object fooObj = pi.GetValue(bar, null);
        ((Foo)fooObj).FooHasAMethod(); // this works
        /* but I want to use 
         * ((Type.GetType(propertyName))fooObj).FooHasAMethod(); This line needs fix
         * which doesnt work
         * Is there a way to type cast using a string name of a object?
         * */
    }
}
Run Code Online (Sandbox Code Playgroud)

Tej*_*ejs 8

如果您使用的是.NET 4,那实际上很容易= D

dynamic obj = bar;
obj.FooProperty.FooHasAMethod();
Run Code Online (Sandbox Code Playgroud)

但是,如果您只想将结果转换为其他类型,则可以在运行时使用Convert.ChangeType方法执行此操作:

object someBoxedType = new Foo();
Bar myDesiredType = Convert.ChangeType(typeof(Bar), someBoxedType) as Bar;
Run Code Online (Sandbox Code Playgroud)

现在,这个与实际类型Foo和Bar有很强的联系.但是,您可以对方法进行泛化以获得所需内容:

public T GetObjectAs<T>(object source, T destinationType)
   where T: class
{
     return Convert.ChangeType(typeof(T), source) as T;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样调用:

Bar x = GetObjectAs(someBoxedType, new Bar());

SomeTypeYouWant x = GetObjectAs(someBoxedType, Activator.CreateInstance(typeof("SomeTypeYouWant")));
Run Code Online (Sandbox Code Playgroud)

使用激活器,您可以在运行时创建所需的任何类型.并且通过推断尝试从boxedType转换为运行时类型来欺骗泛型方法.

另外,如果你只想在一些动态属性值上调用一个方法,那么最佳实践(imo)就是简单地将它作为一些所需的对象.

ISomething propValue = obj.GetProperty("FooPropery").GetValue(obj, null) as ISomething;

if(propValue != null)
    propValue.FooHasAMethod();
Run Code Online (Sandbox Code Playgroud)

  • 如果`T`是一个类,则`Convert.ChangeType`是无用的(除非您使用的是`IConvertible`)。 (2认同)

Dav*_*ale 5

无法转换为编译时未知的类型.

看看.NET 4.0 动态类型.


Art*_*nez 4

Type fooObjType = fooObj.GetType();
MethodInfo method = fooObjType.GetMethod("FooHasAMethod");
method.Invoke(fooObj, new object[0]);
Run Code Online (Sandbox Code Playgroud)