给定“where T:new()”,“new T()”在内部使用Activator.CreateInstance吗?
如果我有一个类型参数约束new()
:
void Foo() where T : new() { var t = new T(); }
new T()
会在内部使用Activator.CreateInstance
方法(即reflection)吗?
是的,这是真的。 编辑2:这是一个很好的解释如何以及为什么。
https://www.simple-talk.com/community/blogs/simonc/archive/2010/11/17/95700.aspx
为了validation,我编译了以下方法:
public static T Create() where T: new() { return new T(); }
这是使用.NET 3.5 SP1中的C#编译器编译时生成的IL:
.method public hidebysig static !!T Create<.ctor T>() cil managed { .maxstack 2 .locals init ( [0] !!T local, [1] !!T local2) L_0000: ldloca.s local L_0002: initobj !!T L_0008: ldloc.0 L_0009: box !!T L_000e: brfalse.s L_001a L_0010: ldloca.s local2 L_0012: initobj !!T L_0018: ldloc.1 L_0019: ret L_001a: call !!0 [mscorlib]System.Activator::CreateInstance() L_001f: ret }
编辑: C#4编译器创建略有不同但相似的代码:
.method public hidebysig static !!T Create<.ctor T>() cil managed { .maxstack 2 .locals init ( [0] !!T CS$1$0000, [1] !!T CS$0$0001) L_0000: nop L_0001: ldloca.s CS$0$0001 L_0003: initobj !!T L_0009: ldloc.1 L_000a: box !!T L_000f: brfalse.s L_001c L_0011: ldloca.s CS$0$0001 L_0013: initobj !!T L_0019: ldloc.1 L_001a: br.s L_0021 L_001c: call !!0 [mscorlib]System.Activator::CreateInstance() L_0021: stloc.0 L_0022: br.s L_0024 L_0024: ldloc.0 L_0025: ret }
在值类型的情况下,它不使用激活器,而只返回default(T)
值,否则它将调用Activator.CreateInstance
方法。
是。 它适用于参考类型。
在以下发布编译的代码上使用ILSpy:
public static void DoWork() where T: new() { T t = new T(); Console.WriteLine(t.ToString()); }
墓内
.method public hidebysig instance void DoWork<.ctor T> () cil managed { // Method begins at RVA 0x2064 // Code size 52 (0x34) .maxstack 2 .locals init ( [0] !!T t, [1] !!T CS$0$0000, [2] !!T CS$0$0001 ) IL_0000: ldloca.s CS$0$0000 IL_0002: initobj !!T IL_0008: ldloc.1 IL_0009: box !!T IL_000e: brfalse.s IL_001b IL_0010: ldloca.s CS$0$0001 IL_0012: initobj !!T IL_0018: ldloc.2 IL_0019: br.s IL_0020 IL_001b: call !!0 [mscorlib]System.Activator::CreateInstance() IL_0020: stloc.0 IL_0021: ldloca.st IL_0023: constrained. !!T IL_0029: callvirt instance string [mscorlib]System.Object::ToString() IL_002e: call void [mscorlib]System.Console::WriteLine(string) IL_0033: ret } // end of method Program::DoWork
或者在C#中:
public void DoWork() where T : new() { T t = (default(T) == null) ? Activator.CreateInstance () : default(T); Console.WriteLine(t.ToString()); }
JIT将为传入的每个不同的值类型参数创建不同的编译指令,但将对引用类型使用相同的指令 – 因此Activator.CreateInstance()
上述就是C#学习教程:给定“where T:new()”,“new T()”在内部使用Activator.CreateInstance吗?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1024513.html