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


当前回答

如前所述,对于方法和类来说,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#在哪些方面没有提供相应的特性,让我感到耳目一新。

其他回答

如前所述,对于方法和类来说,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类final和方法final ->密封。 Java成员变量final -> readonly为运行时常量,const为编译时常量。

没有等价的局部变量final和方法参数final

这取决于上下文。

对于最终的类或方法,c#等效的是密封的。 对于final字段,c#中的等效字段是只读的。 对于最终的局部变量或方法参数,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表达式是在运行时而不是编译时计算的,因此允许使用任意表达式。

这里的每个人都缺少的是Java对最终成员变量的明确赋值的保证。

对于具有最终成员变量V的类C,通过C的每个构造函数的每一个可能的执行路径都必须精确地赋值V一次-未能赋值V或赋值V两次或两次以上将导致错误。

c#的readonly关键字就没有这样的保证——编译器很乐意保留未分配的readonly成员,或者允许你在构造函数中多次分配它们。

因此,final和readonly(至少对于成员变量而言)肯定是不相等的——final要严格得多。