Esta es una pregunta de seguimiento a esta otra pregunta.
Antecedentes
Trabajando desde el Tutorial de delegados de MSDN (C #) , veo lo siguiente:
Tenga en cuenta que una vez que se crea un delegado, el método con el que está asociado nunca cambia: los objetos delegados son inmutables.
Y luego, en el ejemplo de código, veo esto (Extender un poco a través del código):
public delegate void ProcessBookDelegate(Book book);
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(totaller.AddBookToTotal));
La pregunta
Ahora, obviamente, la forma en que se escribe el código aquí se crea un nuevo delegado para cada proceso. Estoy adivinando la inmutabilidad es relevante si se trata de hacer cosas por el estilo
ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);
ProcessBookDelegate thisIsATest = new ProcessBookDelegate(totaller.AddBookToTotal);
que debería ... aún compilar cuando thisIsATest
es inmutable? Entonces, ¿qué problema ha resuelto Microsoft haciéndolo inmutable? ¿Qué problemas tendríamos si C # 6 hiciera mutables a los delegados?
EDITAR
Creo que la inmutabilidad evitará esto:
ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);
thisIsATest.ChangeTheDelegateInABadFashion();
someFunction(thisIsATest); //This function works as normal
//because the delegate is unchanged
//due to immutability
pero la inmutabilidad NO evitará esto:
ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);
thisIsATest = new ProcessBookDelegate(ChangeTheDelegateInABadFashion());
someFunction(thisIsATest); //This function works weird now because
//it expected the unchanged delegate
¿Estoy en lo correcto en este entendimiento?
fuente
Func<int>
que devuelva 1 el primero vez que se llama, 2 el segundo, etc., esto se comporta esencialmente como un objeto mutable.s[2] = 't'
.Razones en resumen:
Consulte estas dos preguntas en Stack Overflow para obtener más información:
fuente
seguridad estándar del hilo, creo; si sabe que un delegado nunca cambiará, puede hacer algunas suposiciones al respecto
en particular, puede estar seguro de que un código malvado no puede cambiar al delegado que está pasando a varias funciones (incluso por accidente)
esto podría causar errores difíciles de rastrear y dejar al programador preguntándose por qué no se llamó a su delegado
fuente
La respuesta simple es mutar a un delegado tiene muy poco sentido. Un delegado es en gran medida una referencia a una función, un conjunto de código de ejecución. Mutar eso sugiere que estás mutando esa función.
Pregúntese, ¿cómo sería ese método en un delegado y qué haría? En cierto sentido, sería reescribir el código de esa función. Eso abre una enorme (casi intratable) complejidad a la especificación de C # y a las implementaciones del compilador para obtener muy pocos beneficios con grandes costos de rendimiento. De ahí la restricción.
fuente