Considérese este fragmento de código y tratar de adivinar lo que y1
y2
y evaluar a¿Por qué estas dos funciones no devuelven el mismo valor?
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..
}
}
Se podría decir -Aha- doble es un tipo de valor por lo que el valor devuelto por el método de extensión es una copia de la principal x
. Pero cuando cambias lo anterior en delegados de clases, los resultados aún son diferentes. Ejemplo:
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
}
De modo que las dos funciones deben devolver dos instancias diferentes de la misma clase. Es interesante considerar que ff()
lleva consigo una referencia a la variable local foo
, pero fg()
no y se basa en lo que está actualmente en el alcance.
Entonces, ¿qué sucede cuando estos dos delegados pasan a otras partes del código que no tienen visibilidad en la instancia foo
? De alguna manera, la cuestión de quién posee qué información (datos) es cada vez menos clara cuando los métodos de extensión se combinan con los delegados.
Cabeceo a esta respuesta debido a la brevedad + claridad + formato. – ja72
Meh ... It a: no se une a * valor * de nada (excepto la instancia de clase de captura de generación de compilador), y b: no se vincula estrictamente a "x" * en absoluto * - más claro sí, pero creo que tal vez un poco engañoso debido a esa simplicidad. (la simplicidad es buena) –
@Marc - es un lanzamiento. Pensé en centrarme en la forma en que parece a un usuario, en lugar de sumergirme en la forma en que se implementó. – Bevan