Mic*_*tum 47 .net c# reflection
我有一个类,其构造函数被定义为内部,这意味着我无法实例化它.虽然这可能有意义,但我仍然希望这样做一次用于调试和研究目的.
用反射可以做到吗?我知道我可以访问私人/内部成员,但我可以调用内部构造函数吗?
或者,由于构造函数没有什么重要的,我可以使用反射来说"看,只需给我一个类的实例而不调用构造函数,我会手动完成它的工作"?
性能和"稳定性"在这里不是问题,因为它不是生产代码.
编辑:正如澄清:遗憾的是,我不控制其他程序集并且没有它的源代码,我只是试图理解它是如何工作的,因为它的文档旁边是不存在的,但我应该与它.
Phi*_*ert 85
另一种方法是将调用程序集指定为"朋友"程序集.
只需将其添加到包含内部构造函数的程序集的AssemblyInfo.cs文件中:
[assembly: InternalsVisibleTo("Calling.Assembly")]
Run Code Online (Sandbox Code Playgroud)
如果您无权访问程序集,也可以直接调用构造函数(使用Reflection):
MyClass obj = (MyClass) typeof(MyClass).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, Type.EmptyTypes, null).Invoke(null);
Run Code Online (Sandbox Code Playgroud)
Ken*_* K. 32
一个FormatterServices.GetUninitializedObject方法存在(命名空间:System.Runtime.Serialization),它理应唤不回构造函数,如果你真的想尝试一下这种方法.
wes*_*ton 21
这是从这个答案得出的方法:
public static T CreateInstance<T>(params object[] args)
{
var type = typeof (T);
var instance = type.Assembly.CreateInstance(
type.FullName, false,
BindingFlags.Instance | BindingFlags.NonPublic,
null, args, null, null);
return (T) instance;
}
Run Code Online (Sandbox Code Playgroud)
示例用法(这是我需要为单元测试创建的Kinect SDK类型):
DiscreteGestureResult a = CreateInstance<DiscreteGestureResult>(false, false, 0.5f);
Run Code Online (Sandbox Code Playgroud)
如果想避免反射,可以使用表达式。下面是使用字符串值调用私有构造函数的示例。
private static Func<string, T> CreateInstanceFunc()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var ctor = typeof(T).GetConstructors(flags).Single(
ctors =>
{
var parameters = ctors.GetParameters();
return parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
});
var value = Expression.Parameter(typeof(string), "value");
var body = Expression.New(ctor, value);
var lambda = Expression.Lambda<Func<string, T>>(body, value);
return lambda.Compile();
}
Run Code Online (Sandbox Code Playgroud)