我最近一直在用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()
    {
        // .....
    }
}

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


当前回答

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

这里是一个不能在声明中初始化的例子,所以它必须在构造函数中完成。 错误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) 
    {
    }
}

其他回答

如果我告诉你,这要看情况?

我通常初始化所有东西,并以一致的方式进行。是的,它过于明确,但它也更容易维护。

如果我们担心性能,那么我只初始化必须要做的事情,并将其放在性价比最高的地方。

在实时系统中,我甚至怀疑我是否需要变量或常数。

在c++中,我经常在这两个地方都不初始化,而是将它移动到Init()函数中。为什么?好吧,在c++中,如果你初始化的东西可能会在对象构造过程中抛出异常,你就会导致内存泄漏。

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

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

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

这不是对你关于最佳实践的问题的直接回答,但一个重要的和相关的复习点是,在泛型类定义的情况下,要么让编译器使用默认值初始化它,要么我们必须使用一个特殊的方法将字段初始化为它们的默认值(如果这对代码可读性绝对必要的话)。

class MyGeneric<T>
{
    T data;
    //T data = ""; // <-- ERROR
    //T data = 0; // <-- ERROR
    //T data = null; // <-- ERROR        

    public MyGeneric()
    {
        // All of the above errors would be errors here in constructor as well
    }
}

将泛型字段初始化为默认值的特殊方法如下:

class MyGeneric<T>
{
    T data = default(T);

    public MyGeneric()
    {           
        // The same method can be used here in constructor
    }
}

我的规则:

不要初始化声明中的默认值(null, false, 0, 0.0…) 如果没有改变字段值的构造函数形参,最好在声明中初始化。 如果字段的值因构造函数形参而改变,则将初始化放在构造函数中。 坚持练习(这是最重要的规则)。

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

在声明时初始化类字段

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

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

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

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