考慮這個代碼片段,並試着猜測什麼y1
和y2
評估爲爲什麼這兩個函數不會返回相同的值?
static class Extensions
{
public static Func<T> AsDelegate<T>(this T value)
{
return() => value;
}
}
class Program
{
static void Main(string[] args)
{
new Program();
}
Program()
{
double x = Math.PI;
Func<double> ff = x.AsDelegate();
Func<double> fg =() => x;
x = -Math.PI;
double y1 = ff(); // y1 = 3.141..
double y2 = fg(); // y2 = -3.141..
}
}
你可能會說-Aha-雙是一個值類型,因此通過擴展方法的返回值是的一個副本主要是x
。但是當你將上面的代碼改爲類的代表時,結果仍然不同。例如:
class Foo
{
public double x;
}
Program()
{
Foo foo = new Foo() { x=1.0 };
Func<Foo> ff = foo.AsDelegate();
Func<Foo> fg =() => foo;
foo = new Foo() { x = -1.0 };
double y1 = ff().x; // y1 = 1.0
double y2 = fg().x; // y2 = -1.0
}
所以這兩個函數必須返回同一個類的兩個不同實例。有趣的是,考慮到ff()
帶有對局部變量foo
的引用,但fg()
沒有,並且它依賴於當前範圍內的內容。
那麼當這兩個代表被傳遞到代碼的其他部分時,如果foo
實例不具有可見性,會發生什麼情況?不管怎樣,當擴展方法與代表組合時,誰擁有什麼信息(數據)變得越來越不明確。
點擊此答案,因爲簡潔+清晰度+格式。 – ja72 2010-11-09 18:21:04
咩...這一個:不綁定到一個*值*的東西(除了編譯器生成捕獲類的實例),和b:不嚴格綁定到「X」 *都* - 更清晰的是,但由於這種簡單性,我認爲可能有點誤導。 (雖然簡單很好) – 2010-11-09 18:39:56
@Marc - 這是一個折騰。我想着重於用戶看起來的方式,而不是深入實施。授予 – Bevan 2010-11-09 20:28:02