Parametro Azione in cui T3 può essere facoltativo

Ho il codice seguente:

public static MyMethod() { ...Do something ProtectedMethod(param1, param2); ...Do something } protected static void ProtectedMethod(IEnumerable param1, string param2, int param3 = 1) { ... Do something } 

Prendi nota del parametro param3 opzionale.

Ora, per diversi motivi, ho bisogno di estrarre il codice del metodo MyMethod nella sua class, ma non posso estrarre ProtectedMethod con esso a causa di tutte le classi che ereditano da questo e ho bisogno di mantenere le modifiche piccole e isolate. Quindi ho pensato che potevo avere un delegato di Action nella nuova classe con la stessa firma di ProtectedMethod.

Il problema è che se dichiaro il delegato in questo modo:

 protected readonly Action<IEnumerable, string, int> m_ProtectedMethod; 

Il codice estratto non piace perché dice che il metodo viene invocato solo con due parametri.

E se dichiaro il delegato in questo modo:

 protected readonly Action<IEnumerable, string> m_ProtectedMethod; 

Quando lo invio come parametro alla nuova class, non mi piace neanche perché il metodo è definito come avente tre parametri non due.

Finora l’unico modo che ho pensato di risolvere è creare una versione sovraccaricata di ProtectedMethod per eliminare il parametro opzionale.

È questa l’unica opzione o c’è un altro modo di farlo poiché ora la scelta preferita è quella di avere parametri opzionali invece di metodi sovraccaricati?

I parametri facoltativi sono un attributo di un metodo o un parametro delegato. Quando si chiama una firma (metodo o delegato) con un parametro facoltativo noto in fase di compilazione, il compilatore inserirà il valore del parametro facoltativo nel callsite.

Il runtime non è a conoscenza dei parametri opzionali, quindi non è ansible creare un delegato che inserisca un parametro opzionale quando viene chiamato.

Invece, è necessario dichiarare un tipo di delegato personalizzato con un parametro facoltativo:

 public delegate void MyDelegate(IEnumerable param1, string param2, int param3 = 1); 

Quando si chiama questo delegato, sarà ansible omettere il terzo parametro, indipendentemente dalla dichiarazione dei metodi che contiene.

m_ProtectedMethod come verrà consumato m_ProtectedMethod , ma ho trovato un compromesso nella mia situazione, dove utilizzo un sovraccarico più dell’altro.

Basta definire una più semplice (con parametri meno generici) Action <> variabile , che chiama il metodo di variabile Action più complesso fornito. Questo può essere realizzato in (i) ambito locale in uso; o (ii) portata dell’object al momento dell’assegnazione della proprietà Action o costruzione dell’object.

Poiché non esiste un sovraccarico di proprietà / variabili, sono necessari due nomi diversi, per le due variabili di azione correlate risultanti.

EG i: Local Scope (probabilmente non è il più adatto per il tuo scenario)

 public MyMethod(Action, string, int> m_ProtectedMethod2) { Action, string> m_ProtectedMethod = (p1,p2) => { m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter } ...Do something m_ProtectedMethod(param1, param2); ...Do something ...If something m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly ...Do something } 

EG ii: Object Scope

 private Action, string, int> m_ProtectedMethod2 = null; private Action, string> m_ProtectedMethod = null; protected Action, string, int> ProtectedMethod { get { return m_ProtectedMethod2; } set { m_ProtectedMethod2 = value; m_ProtectedMethod = (p1,p2) => { m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter } } } public MyMethod() { ...Do something m_ProtectedMethod(param1, param2); ...Do something ...If something m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly ...Do something } 

Nota in entrambi i casi ho progettato il valore di impostazione predefinito come la variabile con nome più scomodo, con il suffisso 2, in modo tale che al momento del consumo il sovraccarico più semplice abbia il nome della variabile più semplice.