2

跟进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("")]由于我目前正在解决的错误而无法正常工作。有关原始问题,请参见此处

4

3 回答 3

1

鉴于您只在执行时知道类型,因此实际上没有“将对象作为内部类型返回”这样的概念。考虑一下您希望方法签名的样子……您无法表达它。

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

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

...但是如果调用代码知道它,那对它没有帮助。

如果你能解释更多关于你为什么认为你想要这种能力的原因,我们可以尝试提出替代方案。

于 2010-08-18T15:18:46.377 回答
1

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

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

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

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

几个选择:

  • 修改内部类以实现某个接口,并将该接口公开。正常调用接口上的方法。
  • 开始[InternalsVisibleTo]工作。这是正确的方法。
于 2010-08-18T15:19:40.667 回答
1

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

暴露对象

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

于 2010-08-18T15:21:07.127 回答