当前位置:  开发笔记 > 编程语言 > 正文

在构造函数或声明中初始化类字段?

如何解决《在构造函数或声明中初始化类字段?》经验,为你挑选了5个好方法。

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

我真的很好奇你们有些人认为最好的做法.我想保持一致并坚持一种方法.



1> kokos..:

我的规则:

    使用默认值在声明中没有初始化(null,false,0,0.0...).

    如果您没有更改字段值的构造函数参数,则首选声明中的初始化.

    如果由于构造函数参数而改变字段的值,则将初始化放在构造函数中.

    在你的实践中保持一致(最重要的规则).


我不同意规则1 - 没有指定默认值(无论是否由编译器初始化)你要离开开发人员*猜*或者去寻找关于该特定语言的默认值是什么的文档.出于可读性目的,我总是指定默认值.
我不同意那些不同意规则1的人.期望别人学习C#语言是可以的.正如我们不会对每个`foreach`循环注释"这会对列表中的所有项重复以下内容",我们不需要不断重述C#的默认值.我们也不需要假装C#具有未初始化的语义.由于缺少一个值具有明确的含义,所以可以将其删除.如果明确是理想的,那么在创建新代理时应始终使用`new`(如C#1中所要求的那样).但谁这样做?该语言专为认真的编码人员而设计.
类型`default(T)`的默认值始终是内部二进制表示为"0"的值.
无论您是否喜欢规则1,它都不能与只读字段一起使用,*必须*在构造函数完成时显式初始化.
我希望kokos意味着你不应该将成员初始化为它们的默认值(0,false,null等),因为编译器会为你做(1).但是,如果要将字段初始化为除默认值以外的任何值,则应在声明(2.)中执行此操作.我认为可能是使用"默认"这个词让你感到困惑.
使用默认值进行显式初始化会向我建议在其他任何内容写入之前可能会读取该值; 因此,我认为这些声明在含义正确的情况下是有用的.

2> Quibblesome..:

在C#中没关系.您提供的两个代码示例完全相同.在第一个例子中,C#编译器(或它是CLR?)将构造一个空构造函数并初始化变量,就像它们在构造函数中一样.如果已有构造函数,则"上方"的任何初始化将被移动到其顶部.

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


+1构造函数链接参数很强
实际上它确实很重要.如果基类构造函数调用在派生类中重写的虚方法(通常是一个坏主意,但可能发生),那么使用实例变量初始化程序时,该变量将在调用方法时初始化 - 而使用初始化构造函数,他们不会.(在调用基类构造函数之前*执行实例变量初始值设定项.)
如果您选择使用GetUninitializedObject初始化类,那么这是不正确的.无论在ctor中的任何内容都不会被触及,但是现场声明将被运行.
真?我发誓我是通过C#(我认为是第二版)从Richter的CLR中获取此信息的,其要旨是这是语法糖(我可能看错了吗?),而CLR只是将变量塞入了构造函数中。但是您要说明的不是这种情况,即在疯狂的场景中调用成员初始化可以在ctor初始化之前触发,这是在基本ctor中调用虚拟并在所讨论的类中进行覆盖。我理解正确吗?您刚刚发现了吗?对于这个关于5岁帖子的最新评论感到困惑(OMG已经5年了?)。

3> Tom Hawtin -..:

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

如果可以,请将字段设为最终字段.



4> xji..:

我认为有一点需要注意.我曾经犯过这样一个错误:在派生类中,我试图"初始化声明"从抽象基类继承的字段.结果是存在两组字段,一组是"base",另一组是新声明的字段,调试花了我一些时间.

教训:要初始化继承的字段,你可以在构造函数中完成.



5> Noel..:

假设您的示例中的类型,肯定更喜欢初始化构造函数中的字段.特殊情况是:

静态类/方法中的字段

输入的字段为static/final/et al

我总是将类顶部的字段列表视为目录(此处包含的内容,而不是如何使用),以及构造函数作为简介.方法当然是章节.

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有