2009-07-31 17 views
7

Molto spesso capita di avere metodi privati ​​che diventano molto grandi e contengono attività ripetitive, ma questi compiti sono così specifici che non ha senso renderli disponibili a qualsiasi altra parte di codice.C#: Perché non possiamo avere metodi interni/funzioni locali?

Quindi sarebbe davvero fantastico poter creare "metodi interni" in questo caso.

C'è qualche limite tecnico (o addirittura filosofico?) Che impedisce a C# di darci questo? O mi sono perso qualcosa?

Aggiornamento dal 2016: È in arrivo e si chiama "funzione locale". Vedi risposta contrassegnata.

+0

Cosa c'è di più interno di un metodo privato? Metodi disponibili solo per un metodo? Sembra solo più codice che meno. – kenny

+1

Ti sei perso qualcosa. C# ha avuto questa caratteristica da C# 2.0. –

+0

@Eric Lippert: puoi fornire alcuni dettagli? Grazie. – Marc

risposta

0

sembra che stiamo andando a ottenere esattamente quello che volevo con funzioni locali in C# 7/Visual Studio 15:
https://github.com/dotnet/roslyn/issues/2930

private int SomeMethodExposedToObjectMembers(int input) 
{ 
    int InnerMethod(bool b) 
    { 
     // TODO: Change return based on parameter b 
     return 0; 
    } 

    var calculation = 0; 
    // TODO: Some calculations based on input, store result in calculation 

    if (calculation > 0) return InnerMethod(true); 
    return InnerMethod(false); 
} 

Peccato che ho dovuto aspettare più di 7 anni per questo :-)

Vedere anche altre risposte per le versioni precedenti di C#.

14

Beh, siamo in grado di avere "i metodi anonimi", definiti all'interno di una funzione (io non suggerisco di usare loro di organizzare un metodo di grandi dimensioni):

void test() { 
    Action t =() => Console.WriteLine("hello world"); // C# 3.0+ 
    // Action t = delegate { Console.WriteLine("hello world"); }; // C# 2.0+ 
    t(); 
} 
+0

+1, questo è esattamente quello che vuoi. – Blindy

+0

@Mehrdad Afshari: Sembra interessante, sembra che "Func" possa essere usato per questo. Ma perché non dovresti usarli per organizzare un metodo di grandi dimensioni? – Marc

+0

@Marc: dovresti prendere in considerazione la possibilità di suddividere un metodo di grandi dimensioni in diversi metodi più piccoli, non in metodi anonimi. –

7

Se qualcosa è lungo e complicato del solito il suo bene esercitatevi a rifattorizzarlo su una classe separata (normale o statica, a seconda del contesto) - lì potete avere metodi privati ​​che saranno specifici solo per questa funzionalità.

2

So che a molte persone non piacciono le regioni ma questo è un caso in cui potrebbero rivelarsi utili raggruppando i metodi specifici in una regione.

+0

Questo è quello che faccio già :-) Uso molto le regioni e le classi parziali. – Marc

1

Se il metodo diventa troppo grande, prendere in considerazione la possibilità di inserirlo in una classe separata o di creare metodi di supporto privati. Generalmente creo un nuovo metodo ogni volta che normalmente vorrei scrivere un commento.

+0

Creare un metodo di helper privato è quello che ho fatto fino a quando non lo so, ma di solito finisco con così tanti metodi di helper privati ​​che qualche tempo dopo non so quale metodo privato usi quale metodo privato. Ecco perché mi piacerebbe includere questi metodi di supporto all'interno del metodo che li richiede. – Marc

+0

@Marc, se il metodo diventa troppo grande potrebbe essere il momento di prendere in considerazione la creazione di una nuova classe, ma è difficile dire quale sia l'approccio "giusto" senza conoscere il codice. –

2

Potrebbe fornire un esempio più concreto? Dopo aver letto il tuo post ho la seguente impressione, che è ovviamente solo un'ipotesi, a causa di informazioni limitate:

  • I metodi privati ​​non sono disponibili al di fuori della classe, quindi sono comunque nascosti da qualsiasi altro codice.
  • Se si desidera nascondere metodi privati ​​da un altro codice nella stessa classe, la classe potrebbe essere troppo grande e potrebbe violare la singola regola di responsabilità.
  • Dai un'occhiata ai delegati anonimi e alle espressioni lambda. Non è esattamente quello che hai chiesto, ma potrebbero risolvere la maggior parte dei tuoi problemi.

Achim

+0

Sono d'accordo che le espressioni lambda potrebbero risolvere il mio problema. Anche se si utilizza Func I è possibile passare solo 1 parametro. Mehrdad Afshari ha risposto che non avrebbe usato questo per semplificare i metodi però ... – Marc

0

La soluzione migliore è quella di refactoring questo metodo per separare classe. Crea un'istanza di questa classe come campo privato nella tua classe iniziale. Rendi pubblico il grande metodo e riduci il metodo grande in diversi metodi privati, quindi sarà molto chiaro cosa faccia.

Problemi correlati