【问题标题】:What is the equivalent of Java's final in C#?什么是 C# 中 Java 的 final 等价物?
【发布时间】:2010-11-22 14:08:02
【问题描述】:

C# 中 Java 的 final 等价于什么?

【问题讨论】:

  • 类顶部的评论说“如果你覆盖这个类,你会被解雇!” (当然这是个玩笑:)

标签: c# access-modifiers reserved-words


【解决方案1】:

final 关键字在 Java 中有多种用法。它对应于 C# 中的 sealedreadonly 关键字,具体取决于使用它的上下文。

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

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() {...}
}

正如 Joachim Sauer 所指出的,这两种语言之间的一个显着区别是 Java 默认将所有非静态方法标记为 virtual,而 C# 将它们标记为 sealed。因此,如果您想停止进一步覆盖基类中已显式标记为 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 表达式是在 runtime 而不是 compile-时间,因此允许任意表达式。

【讨论】:

  • 我要补充一点,Java 中的所有非静态方法默认都是虚拟的。因此,虽然在 C# 中您可以简单地在初始定义中省略虚拟,但您需要使用“final”来避免在 Java 中覆盖它的子类
  • 很好的答案——尽管在 java 中还有一种“final”的用法——在局部变量或方法参数上以防止重新分配它。没有与此等效的 c# 直接等效项。
  • readonly 成员变量可以在构造函数中修改:pastebin.com/AzqzYGiA
  • 另请注意:如果您在 Java 中将成员变量声明为 final,编译器会报错,如果不是每个构造函数都在每个代码路径中分配一个值,而 C# 在这种情况下只会发出警告,并带有只读成员变量
  • @NickolayKondratyev:是的,我的例子是隐含的,你需要从另一个类继承。你真的不需要界面;这是多余的,但除此之外看起来还不错。
【解决方案2】:

这取决于上下文。

【讨论】:

  • 实际上并没有要求在声明最终变量时对其进行赋值。 'final' 意味着变量必须在被引用之前由某个代码路径分配,并且没有代码路径允许多次分配变量。这适用于实例变量,这实际上意味着构造函数必须显式分配变量。
  • + for For a final local variable or method parameter, there's no direct C# equivalent 一个巨大的区别。
  • 如果你是 instantiating,可以使用 const 作为局部变量。它不是等价的,因为当然 final 允许您单独声明和初始化(因此具有不同的值),但以防万一您不知道...
  • const 只能用于值类型。据我所知,没有办法为本地引用类型创建一个有效的常量。
  • @jocull 字符串是唯一的例外。
【解决方案3】:

密封

【讨论】:

  • 这只是答案的一部分,因为它取决于上下文并添加解释和/或示例将使需要帮助的人更容易理解
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    Java 类 final 和方法 final -> 密封。 Java 成员变量 final -> 运行时常量为只读,编译时常量为 const。

    局部变量 final 和方法参数 final 没有等效项

    【讨论】:

      【解决方案6】:

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

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

      C# 的 readonly 关键字没有这样的保证 - 编译器非常乐意让 readonly 成员不分配或允许您在构造函数中多次分配它们。

      因此,final 和 readonly(至少就成员变量而言)绝对不等价 - final 更加严格。

      【讨论】:

        【解决方案7】:

        如前所述,sealed 等同于方法和类的final

        其他的就复杂了。

        • 对于static final 字段,static readonly 是最接近的可能。它允许您在静态构造函数中初始化静态字段,这与 Java 中的静态初始化器非常相似。这适用于常量(基元和不可变对象)和对可变对象的常量引用。

          const 修饰符与常量非常相似,但您不能在静态构造函数中设置它们。

        • 在离开构造函数后不应重新分配的字段上,可以使用readonly。但它并不相等 - final 即使在构造函数或初始化程序中也需要一个赋值。

        • 据我所知,final 局部变量没有 C# 等效项。如果您想知道为什么有人需要它:您可以在 if-else 之前声明一个变量,switch-case 左右。通过将其声明为 final,您可以强制它最多分配一次。

          Java 局部变量通常需要在读取之前至少分配一次。除非分支在读取值之前跳出,否则最终变量只会分配一次。所有这些都是在编译时检查的。这需要行为良好的代码,错误余地较小。

        总结起来,C# 没有直接等效于final。虽然 Java 缺少 C# 的一些不错的特性,但作为一个主要是 Java 程序员的我,看到 C# 未能提供同等功能的地方让我感到耳目一新。

        【讨论】:

          猜你喜欢
          • 2010-11-13
          • 2010-12-07
          • 1970-01-01
          • 2011-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多