我最近一直在用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#的设计表明,内联初始化是首选,否则就不会出现在语言中。只要可以避免代码中不同位置之间的交叉引用,通常情况下就会更好。

还有与静态字段初始化的一致性问题,需要内联以获得最佳性能。构造函数设计框架设计指南是这样说的:

考虑内联初始化静态字段,而不是显式使用静态构造函数,因为运行时能够优化没有显式定义静态构造函数的类型的性能。

“考虑”在这里的意思是除非有很好的理由不这样做。对于静态初始化字段,一个很好的理由是初始化太复杂,不能内联编码。

其他回答

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

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

我的规则:

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

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

c#的设计表明,内联初始化是首选,否则就不会出现在语言中。只要可以避免代码中不同位置之间的交叉引用,通常情况下就会更好。

还有与静态字段初始化的一致性问题,需要内联以获得最佳性能。构造函数设计框架设计指南是这样说的:

考虑内联初始化静态字段,而不是显式使用静态构造函数,因为运行时能够优化没有显式定义静态构造函数的类型的性能。

“考虑”在这里的意思是除非有很好的理由不这样做。对于静态初始化字段,一个很好的理由是初始化太复杂,不能内联编码。

Consider the situation where you have more than one constructor. Will the initialization be different for the different constructors? If they will be the same, then why repeat for each constructor? This is in line with kokos statement, but may not be related to parameters. Let's say, for example, you want to keep a flag which shows how the object was created. Then that flag would be initialized differently for different constructors regardless of the constructor parameters. On the other hand, if you repeat the same initialization for each constructor you leave the possibility that you (unintentionally) change the initialization parameter in some of the constructors but not in others. So, the basic concept here is that common code should have a common location and not be potentially repeated in different locations. So I would say always put it in the declaration until you have a specific situation where that no longer works for you.