2011-07-25 22 views
5

Actualmente estoy refacturando un DAL existente que tiene una fachada que el usuario llama y una clase interna que hace el trabajo real depende del proveedor ADO.Net para usar, p. SqlProvider, y yo estoy tratando de asegurarse de que el código está seco, lo he hecho bien mediante el uso de un Func por lo que puedo hacer:C# delegado genérico sin parámetro - definir y llamar

return RunCommand(c => c.ExecuteNonQuery(commandText, parameters)); 

Y el método EjecutarComando se parece a:

private T RunCommand<T>(Func<Commands, T> toRun) 
    { 
     return toRun(CreateCommand()); 
    } 

El El método CreateCommand() simplemente crea el objeto de comando a usar, esto me permite tener un único método que maneja todas las llamadas que acaban de devolver el tipo esperado, por ejemplo DataSet, DataReader, etc

El problema que tengo es que varias llamadas en la fachada proporcionan un parámetro out Sé que debe ser capaz de eliminar el código se repite si puedo utilizar un delegado, pero después de mucho googlear & experimentar tengo no se las arregló para averiguar cómo. El código es:

Commands commands = CreateCommand(); 
return commands.ExecuteNonQuery(out cmd, commandText, parameters); 

Lo que realmente me gustaría hacer es ser capaz de llamar a:

return RunCommand(c => c.ExecuteNonQuery(out cmd, commandText, parameters)); 

que he visto this pregunta existente, sino para la vida de mí no puedo encontrar la manera para convertir eso en lo que necesito.

Este delegado parecería ser lo que necesito private delegate V TestOutParameter<T, U, V>(T a, out U b, V c); pero el código que tengo para llamar simplemente no es correcto:

private V RunCommand<T, U, V>(TestOutParameter<Commands, DbCommand, V> commandToExecute) 
    { 
     DbCommand cmd; 
     return (V)commandToExecute(CreateCommand(), out cmd); 
    } 

¿Alguien puede ayudarme ya que esto ha sido volviendo loco para una ¡semana!

Respuesta

11

Su delegado tiene tres parámetros en lugar de dos. Suponiendo que usted quiere que reflejan Func, en lugar de:

private delegate V TestOutParameter<T, U, V>(T a, out U b, V c); 

usted debe tener:

private delegate V TestOutParameter<T, U, V>(T a, out U b); 

yo personalmente recomiendo que cambiar el nombre a algo así como:

private delegate TResult FuncOut<T1, T2, TResult>(T1 arg1, out T2 arg2) 
+0

que el delegado hace al maestro sentido, que es genial. Sin embargo, todavía me estoy rascando la cabeza sobre cómo voy a llamarlo. El T1 es la clase en la que necesito llamar al método real y que tiene el parámetro out en él. TBH Estoy perdido en cuanto a cómo llamarlo. – Nathan

+0

@Nathan: El cambio en el tipo de delegado debe hacer que el código 'RunCommand' solo se compile sin problemas, siempre que el método' CreateCommand' devuelva 'Commands'. –

+0

Ver aquí es donde sigo fallando :) El código 'RunCommand' es feliz, pero cuando intento usar' return RunCommand (c => c.ExecuteNonQuery (out cmd, commandText, parameters)) 'Me lo dice VS que "no puede usar parámetros de ref o out". Supongo que no estoy usando la sintaxis correcta para llamar al método? – Nathan

Cuestiones relacionadas