在c#中,什么相当于Java的final ?


当前回答

最后一个关键字在Java中有几种用法。它对应于c#中的密封关键字和只读关键字,这取决于使用它的上下文。

防止子类化(从已定义的类继承):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

方法

防止重写虚方法。

Java

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

C#

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

正如Joachim Sauer所指出的,这两种语言之间的一个显著区别是,Java默认情况下将所有非静态方法标记为虚拟方法,而c#则将它们标记为密封方法。因此,如果您希望停止在基类中显式标记为virtual的方法的进一步重写,则只需要在c#中使用sealed关键字。

变量

只允许一个变量被赋值一次:

Java

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

C#

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

顺便说一句,readonly关键字的效果与const关键字的效果不同,因为readonly表达式是在运行时而不是编译时计算的,因此允许使用任意表达式。

其他回答

如前所述,对于方法和类来说,sealed相当于final。

至于其他的,就很复杂了。

For static final fields, static readonly is the closest thing possible. It allows you to initialize the static field in a static constructor, which is fairly similar to static initializer in Java. This applies both to constants (primitives and immutable objects) and constant references to mutable objects. The const modifier is fairly similar for constants, but you can't set them in a static constructor. On a field that shouldn't be reassigned once it leaves the constructor, readonly can be used. It is not equal though - final requires exactly one assignment even in constructor or initializer. There is no C# equivalent for a final local variable that I know of. If you are wondering why would anyone need it: You can declare a variable prior to an if-else, switch-case or so. By declaring it final, you enforce that it is assigned at most once. Java local variables in general are required to be assigned at least once before they are read. Unless the branch jumps out before value read, a final variable is assigned exactly once. All of this is checked compile-time. This requires well behaved code with less margin for an error.

综上所述,c#没有final的直接对等物。虽然Java缺少c#的一些不错的特性,但作为一个Java程序员,看到c#在哪些方面没有提供相应的特性,让我感到耳目一新。

最后一个关键字在Java中有几种用法。它对应于c#中的密封关键字和只读关键字,这取决于使用它的上下文。

防止子类化(从已定义的类继承):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

方法

防止重写虚方法。

Java

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

C#

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

正如Joachim Sauer所指出的,这两种语言之间的一个显著区别是,Java默认情况下将所有非静态方法标记为虚拟方法,而c#则将它们标记为密封方法。因此,如果您希望停止在基类中显式标记为virtual的方法的进一步重写,则只需要在c#中使用sealed关键字。

变量

只允许一个变量被赋值一次:

Java

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

C#

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

顺便说一句,readonly关键字的效果与const关键字的效果不同,因为readonly表达式是在运行时而不是编译时计算的,因此允许使用任意表达式。

这取决于上下文。

对于最终的类或方法,c#等效的是密封的。 对于final字段,c#中的等效字段是只读的。 对于最终的局部变量或方法参数,c#中没有直接的对等物。

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

c#常量使用const关键字声明编译时常量,使用readonly关键字声明运行时常量。在c#和Java语言中,常量的语义是相同的。