有时我不想写一个新行来声明一个Regex对象,所以我写了下面的代码
MatchCollection matchCollection = new Regex("example").Matches(someText);
由于我的知识有限,我认为新的正则表达式("示例")可能在匹配开始之前被垃圾收集,但由于操作速度太快,几乎不可能。
我错了吗?这种编码是一种我应该避免的不良做法吗?
答案 0 :(得分:3)
没有。在实际使用对象之前,对象不可能得到GC。
实际上它(几乎)与:
相同var r = new Regex("example");
MatchCollection matchCollection = r.Matches(someText);
作为证明:这是来自包含上述代码(1)的控制台应用程序的IL和oneliner(2):
单独的变量:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 27 (0x1b)
.maxstack 2
.locals init ([0] string someText,
[1] class [System]System.Text.RegularExpressions.Regex r,
[2] class [System]System.Text.RegularExpressions.MatchCollection matchCollection)
IL_0000: nop
IL_0001: ldstr "s"
IL_0006: stloc.0
IL_0007: ldstr "example"
IL_000c: newobj instance void [System]System.Text.RegularExpressions.Regex::.ctor(string)
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: ldloc.0
IL_0014: callvirt instance class [System]System.Text.RegularExpressions.MatchCollection [System]System.Text.RegularExpressions.Regex::Matches(string)
IL_0019: stloc.2
IL_001a: ret
} // end of method Program::Main
Oneliner:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 25 (0x19)
.maxstack 2
.locals init ([0] string someText,
[1] class [System]System.Text.RegularExpressions.MatchCollection matchCollection)
IL_0000: nop
IL_0001: ldstr "s"
IL_0006: stloc.0
IL_0007: ldstr "example"
IL_000c: newobj instance void [System]System.Text.RegularExpressions.Regex::.ctor(string)
IL_0011: ldloc.0
IL_0012: call instance class [System]System.Text.RegularExpressions.MatchCollection [System]System.Text.RegularExpressions.Regex::Matches(string)
IL_0017: stloc.1
IL_0018: ret
} // end of method Program::Main
您将看到实际代码不一样。从堆栈中推送和弹出一个变量,实际调用有点不同,但就是这样。他们仍然调用同一个对象,只有它存在的地方不同。