Sometimes I dont want to write a new line to declare a Regex object so I write the following code
有时我不想写一个新行来声明一个Regex对象,所以我写下面的代码
MatchCollection matchCollection = new Regex("example").Matches(someText);
With my limited knowledge, I think new Regex("example") might be garbage collected before the Matches start but it is nearly not possible as the operation is so fast.
由于我的知识有限,我认为新的正则表达式(“示例”)可能在匹配开始之前被垃圾收集,但由于操作速度太快,几乎不可能。
Am I wrong? Is this kind of coding a bad practice that I should avoid?
我错了吗?这种编码是一种我应该避免的不良做法吗?
1 个解决方案
#1
3
No. It is not possible that the object gets GC'ed before it is actually used.
不可以。对象在实际使用之前不可能得到GC。
In fact it is (almost) the same as:
实际上它(几乎)与以下相同:
var r = new Regex("example");
MatchCollection matchCollection = r.Matches(someText);
As a proof: here is the IL from an console application containing the code above (1), and a oneliner (2):
作为证明:这是来自包含上面代码(1)的控制台应用程序的IL和oneliner(2):
Seperate variables:
单独的变量:
.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:
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
You will see that the actual code is not the same. The pushes and pops one variable more from the stack, and the actual call is a little different, but that's all there is. They still call the same object, only the place where it exists is different.
您将看到实际代码不一样。从堆栈中推送和弹出一个变量,实际调用有点不同,但这就是全部。它们仍然调用相同的对象,只有它存在的地方是不同的。
#1
3
No. It is not possible that the object gets GC'ed before it is actually used.
不可以。对象在实际使用之前不可能得到GC。
In fact it is (almost) the same as:
实际上它(几乎)与以下相同:
var r = new Regex("example");
MatchCollection matchCollection = r.Matches(someText);
As a proof: here is the IL from an console application containing the code above (1), and a oneliner (2):
作为证明:这是来自包含上面代码(1)的控制台应用程序的IL和oneliner(2):
Seperate variables:
单独的变量:
.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:
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
You will see that the actual code is not the same. The pushes and pops one variable more from the stack, and the actual call is a little different, but that's all there is. They still call the same object, only the place where it exists is different.
您将看到实际代码不一样。从堆栈中推送和弹出一个变量,实际调用有点不同,但这就是全部。它们仍然调用相同的对象,只有它存在的地方是不同的。