tipo puede metodos instrucciones funciones expresiones expresion delegados delegado convertir anonimos anonimas c# .net-3.5 delegates lambda anonymous-methods

c# - puede - Convierta este delegado a un método anónimo o lambda



metodos anonimos c# (4)

Soy nuevo en todas las funciones anónimas y necesito ayuda. He conseguido lo siguiente para trabajar:

public void FakeSaveWithMessage(Transaction t) { t.Message = "I drink goats blood"; } public delegate void FakeSave(Transaction t); public void SampleTestFunction() { Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(FakeSaveWithMessage)); }

Pero esto es totalmente feo y me gustaría que el interior del Do sea un método anónimo o incluso un lambda si es posible. Lo intenté:

Expect.Call(delegate { _dao.Save(t); }).Do(delegate(Transaction t2) { t2.Message = "I drink goats blood"; });

y

Expect.Call(delegate { _dao.Save(t); }).Do(delegate { t.Message = "I drink goats blood"; });

pero estos me dan

No se puede convertir el método anónimo para escribir ''System.Delegate'' porque no es un tipo de delegado ** compilar errores.

¿Qué estoy haciendo mal?

Por lo que Mark Ingram publicó, parece ser la mejor respuesta, aunque nadie lo dijo explícitamente, es hacer esto:

public delegate void FakeSave(Transaction t); Expect.Call(delegate { _dao.Save(t); }).Do( new FakeSave(delegate(Transaction t2) { t.Message = expected_msg; }));


El problema no está en la definición de delegado, es que el parámetro del método Do () es del tipo System.Delegate, y el tipo de delegado generado por el compilador (FakeSave) no se convierte implícitamente a System.Delegate.

Intenta agregar un elenco frente a tu delegado anónimo:

Expect.Call(delegate { _dao.Save(t); }).Do((Delegate)delegate { t.Message = "I drink goats blood"; });


Lo que dijo Mark

El problema es que Do toma un parámetro delegado. El compilador no puede convertir los métodos anónimos en Delegado, solo un "tipo de delegado", es decir, un tipo concreto derivado del Delegado.

Si esa función Do hiciera sobrecargas de Acción <>, Acción <,> ... etc., no necesitarías el reparto.


Pruebe algo como:

Expect.Call(delegate { _dao.Save(t); }).Do(new EventHandler(delegate(Transaction t2) { t2.CheckInInfo.CheckInMessage = "I drink goats blood"; }));

Tenga en cuenta el EventHandler agregado alrededor del delegado.

EDIT: puede que no funcione ya que las firmas de función de EventHandler y el delegado no son las mismas ... La solución que agregó al final de su pregunta puede ser la única.

Alternativamente, puede crear un tipo de delegado genérico:

public delegate void UnitTestingDelegate<T>(T thing);

Para que el delegado no sea específico de la transacción.


Ese es un mensaje de error bien conocido. Consulte el enlace a continuación para una discusión más detallada.

http://staceyw1.wordpress.com/2007/12/22/they-are-anonymous-methods-not-anonymous-delegates/

Básicamente, solo necesitas poner un molde frente a tu delegado anónimo (tu expresión lambda).

En caso de que el enlace se caiga, aquí hay una copia de la publicación:

Son métodos anónimos, no delegados anónimos.
Publicado el 22 de diciembre de 2007 por staceyw1

No es solo un tema de conversación porque queremos ser difíciles. Nos ayuda a razonar sobre qué está sucediendo exactamente. Para que quede claro, * no existe un delegado anónimo. Ellos no existen (todavía no). Son "Métodos anónimos" - punto. Importa la forma en que pensamos en ellos y cómo hablamos de ellos. Echemos un vistazo a la declaración de método anónimo "delegate () {...}". En realidad, se trata de dos operaciones diferentes y, cuando lo pensamos de esta manera, nunca más volveremos a confundirnos. Lo primero que hace el compilador es crear el método anónimo bajo las cubiertas utilizando la firma del delegado inferido como la firma del método. No es correcto decir que el método es "sin nombre" porque tiene un nombre y el compilador lo asigna. Está escondido de la vista normal. Lo siguiente que hace es crear un objeto delegado del tipo requerido para envolver el método. Esto se llama inferencia delegada y puede ser la fuente de esta confusión. Para que esto funcione, el compilador debe ser capaz de descubrir (es decir, inferir) qué tipo de delegado creará. Tiene que ser un tipo concreto conocido. Deja escribir un código para ver por qué.

private void MyMethod() { }

No compila:

1) Delegate d = delegate() { }; // Cannot convert anonymous method to type ‘System.Delegate’ because it is not a delegate type 2) Delegate d2 = MyMethod; // Cannot convert method group ‘MyMethod’ to non-delegate type ‘System.Delegate’ 3) Delegate d3 = (WaitCallback)MyMethod; // No overload for ‘MyMethod’ matches delegate ‘System.Threading.WaitCallback’

La línea 1 no se compila porque el compilador no puede inferir ningún tipo de delegado. Puede ver claramente la firma que deseamos, pero no hay un tipo concreto de delegado que el compilador pueda ver. Podría crear un tipo anónimo de delegado de tipo para nosotros, pero no funciona así. La línea 2 no se compila por una razón similar. Aunque el compilador conoce la firma del método, no le damos un tipo delegado y no solo va a elegir uno que funcione (no qué efectos secundarios podría tener). La línea 3 no funciona porque deliberadamente no coincidimos con la firma del método con un delegado que tiene una firma diferente (como WaitCallback takes y object).

Compila:

4) Delegate d4 = (MethodInvoker)MyMethod; // Works because we cast to a delegate type of the same signature. 5) Delegate d5 = (Action)delegate { }; // Works for same reason as d4. 6) Action d6 = MyMethod; // Delegate inference at work here. New Action delegate is created and assigned.

Por el contrario, estos trabajos. La línea 1 funciona porque le decimos al compilador qué tipo de delegado usar y concuerdan, por lo que funciona. La línea 5 funciona por la misma razón. Tenga en cuenta que usamos la forma especial de "delegar" sin los paréntesis. El compilador deduce la firma de método del molde y crea el método anónimo con la misma firma que el tipo de delegado inferido. La línea 6 funciona porque MyMethod () y Action usan la misma firma.

Espero que esto ayude.

También vea: http://msdn.microsoft.com/msdnmag/issues/04/05/C20/