int iVal = 8;
//iVal == 8
if (iVal == 8){
int iVal = 5;
//iVal == 5
}
//iVal == 8
在c#中,你会得到一个编译器错误:
int iVal = 8;
if(iVal == 8) {
int iVal = 5; //error CS0136: A local variable named 'iVal' cannot be declared in this scope because it would give a different meaning to 'iVal', which is already used in a 'parent or current' scope to denote something else
}
如果查看生成的MSIL,这是有意义的——函数使用的所有变量都在函数开始时定义。看看这个函数:
public static void Scope() {
int iVal = 8;
if(iVal == 8) {
int iVal2 = 5;
}
}
if (true) {
MyClass stackObj; //created on the stack
MyClass heapObj = new MyClass(); //created on the heap
obj.doSomething();
} //<-- stackObj is destroyed
//heapObj still lives
public static void Main()
{
Object a = new Object();
Console.WriteLine("object created");
DoSomething(a);
Console.WriteLine("object used");
a = null;
Console.WriteLine("reference set to null");
}
我在现实世界中见过这样做导致问题的例子。例如,我看到ASP。Net web应用程序最终无法连接到数据库(虽然是很短的一段时间,或者直到web服务器进程重新启动),因为sql server '连接池已满'…也就是说,在如此短的时间内创建了如此多的连接,并且没有显式地释放,以至于没有新的连接可以创建,池中的许多连接虽然不是活动的,但仍然被未分配和未收集的对象引用,因此不能重用。在必要的地方正确处理数据库连接可以确保这个问题不会发生(至少不会,除非你有非常高并发访问)。
using (var db = GetDatabase()) {
// Retrieves array of keys
var keys = db.GetRecords(mySelection);
for(int i = 0; i < keys.Length; i++) {
var record = db.GetRecord(keys[i]);
record.DoWork();
keys[i] = null; // GC can dispose of key now
// The record had gone out of scope automatically,
// and does not need any special treatment
}
} // end using => db.Dispose is called