Qual è l'equivalente del finale di Java in C #?


560

Qual è l'equivalente di Java finalin C #?


131
Un commento in cima alla classe che dice "Se si ignora questa classe, si viene licenziati!" (ovviamente è uno scherzo :)
Hemant il

Risposte:


861

La finalparola chiave ha diversi usi in Java. Corrisponde alle parole chiave sealede sia readonlyin C #, a seconda del contesto in cui viene utilizzato.

Classi

Per impedire la sottoclasse (eredità dalla classe definita):

Giava

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

metodi

Prevenire l'override di un virtualmetodo.

Giava

public class MyClass
{
    public final void myFinalMethod() {...}
}

C #

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Come sottolinea Joachim Sauer, una notevole differenza tra le due lingue qui è che Java per impostazione predefinita contrassegna tutti i metodi non statici come virtual, mentre C # li contrassegna come sealed. Pertanto, è necessario utilizzare la sealedparola chiave in C # solo se si desidera interrompere l'ulteriore sostituzione di un metodo che è stato esplicitamente contrassegnato virtualnella classe base.

variabili

Per consentire l'assegnazione di una variabile una sola volta:

Giava

public final double pi = 3.14; // essentially a constant

C #

public readonly double pi = 3.14; // essentially a constant

Come nota a margine, l'effetto della readonlyparola chiave differisce da quello della constparola chiave in quanto l' readonlyespressione viene valutata in fase di esecuzione anziché in fase di compilazione , consentendo quindi espressioni arbitrarie.


15
Aggiungerei che tutti i metodi non statici in Java sono virtuali per impostazione predefinita. Quindi, mentre in C # puoi semplicemente tralasciare il virtuale nella definizione iniziale, dovrai usare "final" per evitare che le sottoclassi lo ignorino in Java
Joachim Sauer,

167
buona risposta - c'è comunque un altro utilizzo di "final" in java - su una variabile locale o su un parametro di metodo per impedire la riassegnazione. Non esiste un equivalente diretto c # di questo.
serg10

17
readonlyle variabili membro possono essere modificate nei costruttori: pastebin.com/AzqzYGiA
ricorsivo

8
Nota anche: se si dichiara una variabile membro come final in Java, il compilatore si lamenterà, se non tutti i costruttori assegnano un valore in ogni percorso di codice, mentre C # emette un avviso in quello scenario con variabili membro di sola lettura
Mene

1
@NickolayKondratyev: Sì, il mio esempio era implicito nel fatto che devi essere una sottoclasse da un'altra classe. Non hai davvero bisogno dell'interfaccia; è superfluo, ma per il resto sembra giusto.
Noldorin,

180

Dipende dal contesto.


1
In realtà non è necessario assegnare una variabile finale quando viene dichiarata. 'final' significa che la variabile deve essere assegnata da un percorso di codice prima di fare riferimento e nessun percorso di codice consente di assegnare la variabile più di una volta. Questo vale per le variabili di istanza, il che significa che i costruttori devono assegnare esplicitamente la variabile.
Jay,

31
+ per For a final local variable or method parameter, there's no direct C# equivalentuna grande distinzione.
Daniel B. Chapman,

1
Se si crea un'istanza , è possibile utilizzare const per una variabile locale. Non è equivalente perché ovviamente final ti consente di dichiarare e inizializzare separatamente (e quindi avere valori diversi), ma nel caso in cui non lo sapessi ...
Griknok,

3
constpuò essere utilizzato solo su tipi di valore. Per quanto ne so non c'è modo di creare una costante efficace per un tipo di riferimento locale.
Giocate il

2
@jocull Con le stringhe come unica eccezione.
Raimund Krämer,

46

Ciò che manca a tutti qui è la garanzia di Java di assegnazione definita per le variabili dei membri finali.

Per una classe C con la variabile membro finale V, ogni possibile percorso di esecuzione attraverso ogni costruttore di C deve assegnare V esattamente una volta - non riuscire ad assegnare V o assegnare V due o più volte comporterà un errore.

La parola chiave readonly di C # non ha tale garanzia - il compilatore è più che felice di lasciare i membri readonly non assegnati o consentire di assegnarli più volte all'interno di un costruttore.

Quindi, final e readonly (almeno rispetto alle variabili dei membri) non sono assolutamente equivalenti - final è molto più rigoroso.


7

Come accennato, sealedè un equivalente di finalmetodi e classi.

Per il resto, è complicato.

  • Per i static finalcampi, static readonlyè la cosa più vicina possibile. Ti consente di inizializzare il campo statico in un costruttore statico, che è abbastanza simile all'inizializzatore statico in Java. Questo vale sia per le costanti (primitive e oggetti immutabili) sia per i riferimenti costanti a oggetti mutabili.

    Il constmodificatore è abbastanza simile per le costanti, ma non è possibile impostarle in un costruttore statico.

  • Su un campo che non deve essere riassegnato una volta che lascia il costruttore, readonlypuò essere utilizzato. Non è uguale però -final richiede esattamente un incarico anche nel costruttore o nell'inizializzatore.
  • Non esiste un equivalente C # per una finalvariabile locale che conosco. Se ti stai chiedendo perché qualcuno dovrebbe averne bisogno: puoi dichiarare una variabile prima di un if-else, switch-case o simili. Dichiarandolo definitivo, imponi che sia assegnato al massimo una volta.

    Le variabili locali Java in generale devono essere assegnate almeno una volta prima di essere lette. A meno che il ramo non salti prima della lettura del valore, una variabile finale viene assegnata esattamente una volta. Tutto questo viene verificato durante la compilazione. Ciò richiede un codice ben educato con un margine inferiore per un errore.

Riassumendo, C # non ha un equivalente diretto di final. Mentre a Java mancano alcune belle funzionalità di C #, è rinfrescante per me come principalmente un programmatore Java vedere dove C # non riesce a fornire un equivalente.


6

Classe Java finale e metodo finale -> sigillato. Variabile membro Java final -> di sola lettura per la costante di runtime, const per la costante di tempo di compilazione.

Nessun equivalente per il finale della variabile locale e l'argomento del metodo final



0

sigillato


8
Quell'unica parte della risposta poiché dipende dal contesto e dall'aggiunta di una spiegazione e / o esempi la renderà molto più digeribile per coloro che hanno bisogno di aiuto
Rune FS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.