我最近一直在用c#和Java编程,我很好奇初始化我的类字段的最佳位置在哪里。

我应该在申报时申报吗?:

public class Dice
{
    private int topFace = 1;
    private Random myRand = new Random();

    public void Roll()
    {
       // ......
    }
}

或者在构造函数中?:

public class Dice
{
    private int topFace;
    private Random myRand;

    public Dice()
    {
        topFace = 1;
        myRand = new Random();
    }

    public void Roll()
    {
        // .....
    }
}

我很好奇你们这些老兵认为最好的做法是什么。我想保持一致,坚持一种方法。


当前回答

在声明中设置值会略微提高性能。如果你在构造函数中设置它,它实际上被设置了两次(第一次为默认值,然后在ctor中重置)。

其他回答

In Java, an initializer with the declaration means the field is always initialized the same way, regardless of which constructor is used (if you have more than one) or the parameters of your constructors (if they have arguments), although a constructor might subsequently change the value (if it is not final). So using an initializer with a declaration suggests to a reader that the initialized value is the value that the field has in all cases, regardless of which constructor is used and regardless of the parameters passed to any constructor. Therefore use an initializer with the declaration only if, and always if, the value for all constructed objects is the same.

在这里,c#的语义与Java略有不同。在c#中,声明中的赋值在调用超类构造函数之前执行。在Java中,它是在允许使用'this'(对匿名内部类特别有用)之后立即执行的,这意味着两种表单的语义确实匹配。

如果可以的话,让这些字段成为最终结果。

假设您的示例中的类型,肯定更喜欢在构造函数中初始化字段。例外情况包括:

静态类/方法中的字段 字段类型为static/final/et al

我总是认为类顶部的字段列表是目录(这里包含什么,而不是如何使用它),构造函数是介绍。方法当然是章节。

当你不需要一些逻辑或错误处理时:

在声明时初始化类字段

当你需要一些逻辑或错误处理时:

在构造函数中初始化类字段

当初始化值可用时,这工作得很好 初始化可以放在一行上。然而,这种形式 初始化因为简单而有局限性。如果 初始化需要一些逻辑(例如,错误处理或 对于循环填充复杂数组),简单的赋值是不够的。 实例变量可以在构造函数中初始化,其中error 可以使用处理或其他逻辑。

来自https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html。

“更喜欢在声明中初始化”,似乎是一个很好的一般实践。

这里是一个不能在声明中初始化的例子,所以它必须在构造函数中完成。 错误CS0236字段初始化器不能引用非静态字段、方法或属性

class UserViewModel
{
    // Cannot be set here
    public ICommand UpdateCommad { get; private set; }

    public UserViewModel()
    {
        UpdateCommad = new GenericCommand(Update_Method); // <== THIS WORKS
    }

    void Update_Method(object? parameter) 
    {
    }
}