Який еквівалент фіналу Java в C #?


559

Який еквівалент Java finalу C #?


131
Коментар верхнього класу, який говорить: "Якщо ви перекриєте цей клас, вас звільняють!" (Безумовно, це жарт :)
Hemant

Відповіді:


860

У finalJava є ключове слово. Він відповідає як sealedі readonlyключовим словам у C #, залежно від контексту, в якому він використовується.

Заняття

Для запобігання підкласифікації (успадкування від визначеного класу):

Java

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Методи

Попередити переосмислення virtualметоду.

Java

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

C #

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

Як зазначає Йоахім Зауер, помітна різниця між двома мовами тут полягає в тому, що Java за замовчуванням позначає всі нестатичні методи як virtual, тоді як C # позначає їх як sealed. Отже, вам потрібно використовувати sealedключове слово у C # лише тоді, коли ви хочете зупинити подальше переосмислення методу, який явно позначений virtualу базовому класі.

Змінні

Щоб дозволити призначити змінну лише один раз:

Java

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

C #

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

Як бічна примітка, ефект readonlyключового слова відрізняється від constключового слова тим, що readonlyвираз оцінюється під час виконання, а не під час компіляції , отже, допускаючи довільні вирази.


15
Додам, що всі нестатичні методи на Java за замовчуванням є віртуальними. Тож у C # ви можете просто залишити віртуальне в початковому визначенні, вам потрібно буде використовувати "остаточний", щоб уникнути підкласів, які його перекривають на Java
Йоахім Зауер

166
хороша відповідь - є ще одне використання "final" в java, хоча - для локальної змінної або параметра методу, щоб запобігти перепризначенню. Не існує прямого еквівалента c #.
serg10

17
readonlyЗмінні учасника можуть бути змінені в конструкторах: pastebin.com/AzqzYGiA
рекурсивна

8
Також зверніть увагу: Якщо ви оголосили змінну члена як остаточну на Java, компілятор поскаржиться, якщо не кожен конструктор призначає значення у кожному кодовому шляху, тоді як C # видає лише попередження за цим сценарієм зі змінними для повторного членства
Mene

1
@NickolayKondratyev: Так, мій приклад мав на увазі те, що вам потрібно підкласифікувати з іншого класу. Інтерфейс вам дійсно не потрібен; це зайве, але в іншому випадку все виглядає правильно.
Нолдорін

180

Це залежить від контексту.


1
Насправді немає вимоги, щоб під час декларації була присвоєна остаточна змінна. "остаточний" означає, що змінна повинна бути призначена деяким кодовим шляхом до посилання, і жоден шлях коду не може присвоювати змінну більше одного разу. Це стосується змінних екземплярів, що фактично означає, що конструктори повинні чітко присвоювати цю змінну.
Jay

31
+ за For a final local variable or method parameter, there's no direct C# equivalentвеличезну відмінність.
Даніель Б. Чапман

1
Якщо ви створюєте інстанцію , const для локальної змінної може бути використаний. Це не рівнозначно, оскільки, звичайно, фінал дозволяє вам окремо декларувати та ініціалізувати (і так мають різні значення), але про всяк випадок, коли ви цього не знали ...
Griknok

3
constможе використовуватися лише для типів значень. Наскільки я знаю, немає можливості зробити ефективну константу для локального типу.
jocull

2
@jocull З єдиними винятками є рядки.
Раймунд Кремер

46

Чого всі тут відсутні, - це гарантія Java на певне призначення змінних остаточного члена.

Для класу C із змінною кінцевого члена V кожен можливий шлях виконання через кожен конструктор C повинен призначати V рівно один раз - якщо не призначити V або призначити V два або більше разів, це призведе до помилки.

Ключове слово для читання лише у C # не має такої гарантії - компілятор із задоволенням залишає члени, які читають лише, без призначення або дозволяють призначити їх кілька разів у конструкторі.

Отже, остаточне та лише для читання (принаймні, стосовно змінних членів), безумовно, не рівнозначні - остаточний набагато суворіший.


7

Як згадувалося, sealedце еквівалент finalметодів та класів.

Щодо решти, то це складно.

  • Для static finalполів static readonly- це найближча річ. Це дозволяє ініціалізувати статичне поле в статичному конструкторі, що досить схоже на статичний ініціалізатор на Java. Це стосується як констант (примітивів і незмінних об'єктів), так і постійних посилань на об'єкти, що змінюються.

    constМодифікатор дуже схожий на константи, але ви не можете встановити їх в статичному конструкторі.

  • На полі, яке не повинно бути перепризначене, як тільки він вийде з конструктора, readonlyможна використовувати. Це не рівно, але finalвимагає рівно одного завдання навіть у конструкторі чи ініціалізаторі.
  • Для finalлокальної змінної, про яку я знаю, немає жодного еквівалента C # . Якщо вам цікаво, навіщо це комусь потрібно? Ви можете оголосити змінну перед тим, як інше, регістр комутатора тощо. Оголосивши його остаточним, ви дотримуєтесь того, що він призначається не більше одного разу.

    Локальні змінні Java загалом повинні бути призначені принаймні один раз перед їх читанням. Якщо гілка не вискочить перед читанням значення, остаточна змінна призначається рівно один раз. Все це перевіряється під час збирання. Для цього потрібен добре поводиться код з меншою відмінністю для помилки.

Підсумований, C # не має прямого еквівалента final. У той час як Java не має деяких приємних функцій C #, це освіжає мене, як правило, програміста Java, щоб побачити, де C # не вдається доставити еквівалент.


6

Кінцевий клас Java та метод остаточний -> герметичний. Змінна члена Java - остаточна - для читання лише для константи виконання, const - для константи часу компіляції.

Немає еквівалента для фіналу локальної змінної та аргументу методу


5

http://en.csharp-online.net/CSharp_FAQ:_What_are_the_differences_bet between_CSharp_and_Java_constant_declarations

Константи C # оголошуються за допомогою ключового слова const для констант часу компіляції або ключового слова readonly для констант часу виконання. Семантика констант однакова і для мов C # та Java.


0

запечатаний


8
Це лише частина відповіді, оскільки це залежить від контексту, а додавання пояснень та / або прикладів зробить його набагато більш корисним для тих, хто потребує допомоги
Rune FS,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.