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

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


当前回答

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

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

其他回答

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

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

在c#中,这并不重要。您给出的两个代码示例完全相同。在第一个例子中,c#编译器(或者是CLR?)将构造一个空构造函数并初始化变量,就像它们在构造函数中一样(Jon Skeet在下面的评论中解释了其中的细微差别)。 如果已经有一个构造函数,那么任何“上面”的初始化都将被移动到它的顶部。

就最佳实践而言,前者比后者更不容易出错,因为有人可能很容易添加另一个构造函数而忘记链接它。

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

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

我通常尝试构造函数不做任何事情,只是获取依赖项并初始化相关的实例成员。如果您想对类进行单元测试,这将使您的工作更加轻松。

如果要分配给实例变量的值不受要传递给构造函数的任何参数的影响,则在声明时分配它。

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.