如何调用只有私有构造函数的类

作者试用ObjectSpaces时,发现其能调用只有私有构造函数的类,借助Reflector分析学会此技巧。不能通过Reflection直接创建此类实例,但可通过偏门技巧绕过限制,还给出了调用缺省构造函数创建对象实例的代码步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我试用ObjectSpaces时,ObjectSpaces竟然能够调用只有私有构造函数的类。例如:

None.gifClass A
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
private A() dot.gif{}
ExpandedBlockEnd.gif}

ObjectSpaces能够创建A的实例,我刚看到的时候,吃了一惊,呵呵…… 后来,借助Reflector分析整理学会了此技巧。

你不能通过Reflection直接创建只有私有构造函数的类,但是你可以通过一些偏门技巧绕过此限制。

其大概思路这样的:

None.gifprivate CreateInstanceDelegate<T> BuildDelegate<T>()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifType type 
= typeof(T);
InBlock.gif
InBlock.gifAssemblyName assemblyName 
= new AssemblyName();
InBlock.gifassemblyName.Name 
= "System.Data.ObjectSpaces.Dynamic";
InBlock.gif
InBlock.gifAssemblyBuilder assemblyBuilder 
InBlock.gif
= AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
InBlock.gif
InBlock.gifModule module 
InBlock.gif
= assemblyBuilder.DefineDynamicModule("WebData""DynamicAssembly.dll"true);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gifType[] paramTypeArray 
= new Type[] dot.gif{};
InBlock.gifType rtnType 
= type;
InBlock.gifString methodName 
= "call_privateCtor";
InBlock.gif
bool skipVisibility = true;
InBlock.gif
InBlock.gifDynamicMethod method 
= new DynamicMethod(
InBlock.gifmethodName,
InBlock.gifrtnType, 
InBlock.gifparamTypeArray, 
InBlock.gifmodule,
InBlock.gifskipVisibility
InBlock.gif);
InBlock.gif
InBlock.gifConstructorInfo ctor 
= type.GetConstructor(
InBlock.gifBindingFlags.NonPublic 
| BindingFlags.Public | BindingFlags.Instance,
InBlock.gif
null,
InBlock.gif
new Type[0],
InBlock.gif
null
InBlock.gif);
InBlock.gif
InBlock.gifILGenerator ilGen 
= method.GetILGenerator();
InBlock.gifilGen.Emit(OpCodes.Newobj, ctor);
InBlock.gifilGen.Emit(OpCodes.Ret);

以上是思路,我们也来写一段代码,让其能够调用缺省构造函数创建对象实例,具体代码:

第一步, 定义一个Delegate:

None.gifpublic delegate T CreateInstanceDelegate<T>();

第二步,定义构建Delegate的方法,关键在此:

None.gifprivate CreateInstanceDelegate<T> BuildDelegate<T>()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifType type 
= typeof(T);
InBlock.gif
InBlock.gifAssemblyName assemblyName 
= new AssemblyName();
InBlock.gifassemblyName.Name 
= "System.Data.ObjectSpaces.Dynamic";
InBlock.gif
InBlock.gifAssemblyBuilder assemblyBuilder 
InBlock.gif
= AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
InBlock.gif
InBlock.gifModule module 
InBlock.gif
= assemblyBuilder.DefineDynamicModule("WebData""DynamicAssembly.dll"true);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gifType[] paramTypeArray 
= new Type[] dot.gif{};
InBlock.gifType rtnType 
= type;
InBlock.gifString methodName 
= "call_privateCtor";
InBlock.gif
bool skipVisibility = true;
InBlock.gif
InBlock.gifDynamicMethod method 
= new DynamicMethod(
InBlock.gifmethodName,
InBlock.gifrtnType, 
InBlock.gifparamTypeArray, 
InBlock.gifmodule,
InBlock.gifskipVisibility
InBlock.gif);
InBlock.gif
InBlock.gifConstructorInfo ctor 
= type.GetConstructor(
InBlock.gifBindingFlags.NonPublic 
| BindingFlags.Public | BindingFlags.Instance,
InBlock.gif
null,
InBlock.gif
new Type[0],
InBlock.gif
null
InBlock.gif);
InBlock.gif
InBlock.gifILGenerator ilGen 
= method.GetILGenerator();
InBlock.gifilGen.Emit(OpCodes.Newobj, ctor);
InBlock.gifilGen.Emit(OpCodes.Ret);
InBlock.gif
InBlock.gif
return (CreateInstanceDelegate<T>) method.CreateDelegate(typeof(CreateInstanceDelegate<T>));
ExpandedBlockEnd.gif}

None.gif
None.gif

第三步,定义创建实例的方法:

None.gifpublic T CreateInstance<T>()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifCreateInstanceDelegate
<T> createInstDelegate = BuildDelegate<T>();
InBlock.gif
return createInstDelegate();
ExpandedBlockEnd.gif}

第四步,如此使用:
定义一个私有缺省构造函数的类

None.gifclass A
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
private A() dot.gif{}
ExpandedBlockEnd.gif}

创建实例的代码:

None.gifA a = CreateInstance<A>();
None.gifConsole.WriteLine(
"create A instance");
None.gif

转载于:https://www.cnblogs.com/jobs/archive/2004/07/07/22196.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值