Что эквивалентно финалу Java в C #?

560

Что эквивалентно Java finalв C #?

Nosrama
источник
131
Комментарий в верхней части класса, говорящий «Если вы переопределите этот класс, вы уволены!» (конечно, это шутка :)
Hemant

Ответы:

861

finalКлючевое слово имеет несколько использований в Java. Это соответствует как sealedиreadonly ключевым словам в C #, в зависимости от контекста , в котором она используется.

Классы

Чтобы предотвратить создание подклассов (наследование от определенного класса):

Ява

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

методы

Предотвратить переопределение virtualметода.

Ява

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

C #

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

Как отмечает Joachim Sauer, заметное различие между этими двумя языками заключается в том, что Java по умолчанию помечает все нестатические методы как virtual, тогда как C # помечает их как sealed. Следовательно, вам нужно использовать sealedключевое слово в C # только в том случае, если вы хотите прекратить дальнейшее переопределение метода, который был явно отмечен virtualв базовом классе.

переменные

Чтобы разрешить присвоение переменной только один раз:

Ява

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 # вы можете просто опустить виртуальное в первоначальном определении, вам нужно будет использовать «final», чтобы избежать переопределения его подклассами в Java
Joachim Sauer
167
хороший ответ - есть еще одно использование «final» в java - для локальной переменной или параметра метода, чтобы предотвратить его переназначение. Там нет C # прямой эквивалент этого.
serg10
17
readonlyпеременные-члены могут быть изменены в конструкторах: pastebin.com/AzqzYGiA
рекурсивный
8
Также обратите внимание: если вы объявите переменную-член как окончательную в Java, компилятор будет жаловаться, если не каждый конструктор присваивает значение каждому пути кода, в то время как C # выдает предупреждение в этом сценарии только для переменных-членов, доступных только для чтения
Mene
1
@NickolayKondratyev: Да, мой пример подразумевался в том, что вам нужно создать подклассы из другого класса. Вам не нужен интерфейс на самом деле; это излишне, но в остальном это выглядит правильно.
Нолдорин
180

Это зависит от контекста.

LukeH
источник
1
На самом деле не требуется, чтобы конечная переменная была назначена при ее объявлении. 'final' означает, что переменная должна быть назначена некоторым путем кода, прежде чем на нее будет ссылаться, и ни один путь кода не позволяет назначать переменную более одного раза. Это относится к переменным экземпляра, что фактически означает, что конструкторы должны назначить переменную явно.
Джей
31
+ за For a final local variable or method parameter, there's no direct C# equivalentогромное различие.
Дэниел Б. Чепмен
1
Если вы создаете экземпляр , можно использовать const для локальной переменной. Это не эквивалентно, потому что, конечно, final позволяет вам отдельно объявлять и инициализировать (и поэтому иметь разные значения), но на тот случай, если вы не знали ...
Griknok
3
constможет использоваться только для типов значений. Насколько я знаю, нет способа создать эффективную константу для локального ссылочного типа.
Jocull
2
@jocull Со строками, являющимися единственным исключением.
Раймунд Крамер
46

Чего здесь не хватает, так это гарантии Java определенного присваивания конечных переменных-членов.

Для класса C с конечной переменной-членом V каждый возможный путь выполнения через каждый конструктор C должен назначать V ровно один раз - если не назначить V или назначить V два или более раз, это приведет к ошибке.

Ключевое слово readonly в C # не дает такой гарантии - компилятор будет рад оставить элементы readonly неназначенными или позволить вам назначать их несколько раз в конструкторе.

Таким образом, final и readonly (по крайней мере, в отношении переменных-членов) определенно не эквивалентны - final намного строже.

Какой-то парень
источник
7

Как уже упоминалось, sealedявляется эквивалентом finalдля методов и классов.

В остальном все сложно.

  • Для static finalполейstatic readonly это самая близкая вещь возможная. Это позволяет вам инициализировать статическое поле в статическом конструкторе, который довольно похож на статический инициализатор в Java. Это относится как к константам (примитивам и неизменным объектам), так и к константным ссылкам на изменяемые объекты.

    constМодификатор очень похож на константы, но вы не можете установить их в статическом конструкторе.

  • readonlyМожно использовать поле, которое не следует переназначать после выхода из конструктора . Это не равно, хотя -final требует ровно одного присваивания даже в конструкторе или инициализаторе.
  • Не существует эквивалента C # для finalлокальной переменной, о которой я знаю. Если вам интересно, зачем кому-то это нужно: вы можете объявить переменную до if-else, switch-case или около того. Объявив его окончательным, вы обязуетесь назначить его не более одного раза.

    Локальные переменные Java в общем случае должны быть назначены хотя бы один раз перед их чтением. Если ветвь не выскакивает до считывания значения, окончательная переменная назначается ровно один раз. Все это проверено во время компиляции. Это требует хорошего поведения кода с меньшим запасом на ошибку.

Подводя итог, C # не имеет прямого эквивалента final. Хотя в Java отсутствуют некоторые приятные возможности C #, мне, как программисту на Java, очень приятно видеть, где C # не может предоставить эквивалент.

Vlasec
источник
6

Класс Java final и метод final -> загерметизированы. Переменная-член Java final -> readonly для постоянной времени выполнения, const для постоянной времени компиляции.

Нет эквивалента для локальной переменной final и метода final

Vijayakumarpl
источник
5

http://en.csharp-online.net/CSharp_FAQ:_What_are_the_differences_between_CSharp_and_Java_constant_declarations

Константы C # объявляются с использованием ключевого слова const для констант времени компиляции или ключевого слова readonly для констант времени выполнения. Семантика констант одинакова как в языках C #, так и в языках Java.

Кшиштоф Красонь
источник
0

запечатанный

x2.
источник
8
Это только часть ответа, поскольку он зависит от контекста и добавления объяснений и / или примеров, которые сделают его более понятным для тех, кто нуждается в помощи
Rune FS