繁体   English   中英

C# - 将Reflection.PropertyInfo对象转换为其Type

[英]C# - Casting a Reflection.PropertyInfo object to its Type

在我的应用程序中,我有一个名为'property'的Reflection.PropertyInfo变量。 当我执行property.GetValue(myObject,null) ,值为Master.Enterprise Enterprise是我的应用程序中的一个类。 因此,'property'包含对我的应用中的类的引用。

在运行时,我想以某种方式将'property'转换为它的类型( Master.Enterprise ),所以我可以使用它,就像它是类类型一样。

我知道这可以做到,因为当我查看调试器中的代码时,调试器正确地将'property'转换为它引用的类型,并且我可以在调试器中看到Enterprise类的所有属性。

我该怎么做呢?

听起来像你需要定义一个接口 - 然后你可以要求你的属性返回一个实现该接口的对象,然后你就可以转换到该接口,而不管是哪个类实现了该接口:

IEnterprise enterprise = (IEnterprise)property.GetValue(myObject, null);

您拥有的唯一选择是使用反射在返回的对象上调用方法和属性 - 这是visual studio调试器正在执行的操作。

Master.Enterprise enterprise = (Master.Enterprise)property.GetValue(myObject,null);

要么

Master.Enterprise enterprise = property.GetValue(myObject,null) as Master.Enterprise;

如果类型不兼容,第一个将抛出异常。 如果不兼容,第二个将返回null。

如果类型在编译时未知,并且您不能假设它实现了已知的接口,则无法将其转换为该类型,因为c#是静态类型语言。

如果您想等待它/使用测试版,您可以使用c#4.0执行此操作,例如:

dynamic obj=property.GetValue(myObject,null);
obj.CallSomeMethod();

但请注意,内部只会调用反射方法来确定如何执行此操作。 你可以通过自己广泛的反思来做到这一点。 如果您向我们提供有关您对返回对象的具体要求的更多信息,我将能够为您提供更详细的答案。

如果你有一个Type Name字符串,你可以这样做:

Assembly execAsm = Assembly.GetExecutingAssembly();
object instance = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(execAsm.FullName, "RipperWorkbench.Classes.LoadManager"); // the type name cam come from a variable or someplace else.

然后你可以把它投射到你需要的类型

Master.Enterprise ent = obj as Master.Enterprise;
if (obj != null) 
{
     ...
}

或者,让对象实现一个接口:您必须确保将类型加载到当前AppDomain中,否则无法反映该类型。

Assembly asm = Assembly.GetExecutingAssembly();

// The executing assembly can change also; so you can load types from other assemblies
// use this if the type isn't loaded in this AppDomain yet.
//Assembly asm = Assembly.LoadFile("path to assembly here", new Evidence());

String typeToLoad = "Master.Enterprise"; // this can be from a config or database call
Type objType = asm.GetType(typeToLoad, true);

if (!objType.IsPublic)
return null;

// make sure the type isn't Abstract
if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract))
    return null;

// IEnterprise is the interface that all of the plugin types must implement to be loaded
Type objInterface = objType.GetInterface("IEnterprise", true);

if (objInterface == null)
    return null;

    var iri = (IEnterprise)Activator.CreateInstance(objType);
    return iri;

将来你可以使用dynamic 现在我觉得你应该使用带有界面的解决方案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM