代码之家  ›  专栏  ›  技术社区  ›  Terrance

实例化内部类并将其强制转换为给定类型

  •  2
  • Terrance  · 技术社区  · 14 年前

    跟进 InternalsVisibleTo . 我已经看过了 c# Instantiating Internal class with private constructor ,这是有帮助的,但我正在尝试将返回的对象强制转换为内部类型,老实说,我并不是100%认为这是可能的。

    我正在尝试反射路径来解决这个问题,但是我很难找到如何用反射的私有方法实例化内部类型。我可以一直拉类型、获取构造函数和创建对象。

    如果要强制转换的类型是内部类型,我将如何执行对象的强制转换?

    public object InitPrivateCoreObjects(string Type)
    {
        Assembly Core = Assembly.Load("Stuff.Core, Version=0.3.3881.21340, Culture=neutral, PublicKeyToken=4fe470e63e2d354e");
        Type TypeToReflect = Core.GetType("Stuff.Core.AssemblyWithIdentifer");
        object o = Activator.CreateInstance(TypeToReflect);
        MethodInfo mi = TypeToReflect.GetMethod("AssemblyWithIdentifer");
        object newObject = mi.Invoke(o,null);
        //alternatively
        //ConstructorInfo ctor = TypeToReflect.GetConstructor(new Type[]{TypeToReflect.GetType()});
        //ctor.Invoke(newObject, null);
    
        return newObject;
    }
    

    我可以得到内部类的类型,
    我可以调用构造函数并实例化该类型的对象。但是,由于我没有任何访问内部类型的权限,因此我无法从内部类型进行强制转换和操作。

    我知道我可以用 Reflection.Emit 创建一个基于该类型的新类,但是如果我要走这条路线,那么我也可以复制我试图访问测试项目的整个项目内容。这将是非常浪费和毫无意义的,需要我从其他项目中投入东西,造成混乱,这绝对不是我现在想走的路线。

    我看到过访问单个方法和属性的示例,但没有实例化整个类的实例。我不能100%肯定这是可能的,因为按照操作顺序,反射发生在访问修饰符被查看之前。

    这能做到吗?如果可以,怎么做?

    为了清晰起见,我想使用实例化的对象进行测试,并且 [Assembly:InternalsVisibleTo("")] 由于我目前正在处理的错误而无法工作。见 here 对于原始问题。

    3 回复  |  直到 14 年前
        1
  •  0
  •   Jon Skeet    14 年前

    考虑到您在执行时只知道类型,实际上没有“将对象返回为内部类型”这样的概念。想想你希望方法签名看起来像什么…你无法表达它。

    如果调用代码以强类型的方式了解它,则应改为使代码通用:

    public T InitPrivateCoreObjects<T>()
    {
        Type type = typeof(T);
        ...
        return (T) newObject;
    }
    

    …但是如果呼叫码 知道这件事,对它没有帮助。

    如果你能解释更多为什么你认为你想要这个能力,我们可以尝试建议改变。

        2
  •  1
  •   Tim Robinson    14 年前

    我可以使用Reflection.Emit创建基于该类型的新类

    并非如此:使用反射生成的代码。Emit遵循与您自己的C相同的规则。你不能用它来绕过 internal 保护。

    我看到过访问单个方法和属性的示例

    这就是您需要做的:使用反射来查找和调用各个方法和属性。

    几个备选方案:

    • 修改内部类以实现某些接口,并使该接口成为公共接口。正常调用接口上的方法。
    • 得到 [InternalsVisibleTo] 工作。 这是正确的方法。
        3
  •  1
  •   Ani    14 年前

    这并不是你问题的直接答案,但你会发现这很有用:

    ExposedObject

    如果您没有访问内部类型的权限,并且该类型也没有实现任何您认为足以与之交互的公共接口, 但是 您事先知道该类型成员的姓名和签名,这可能是您的最佳选择。