变量初始化:直接还是在构造函数中?
可能重复:
最佳实践:在构造函数或声明中初始化类字段?
大多数时候,我看到了像这样初始化变量的方法
public class Test { private int myIntToInitalize; public Test() { myIntToInitalize = 10; } }
从我的角度来看,这是初始化变量的最常用方法。 书籍,博客以及.NET的内部实现中的大多数代码都与我的示例相同。
最近我看到人们直接进行初始化,所以没有在构造函数中设置值。
public class Test { private int myIntToInitalize = 10; }
从观点来看,初始化和声明变量或初始化构造函数中的变量没有区别。
除了最佳实践和代码行的长度,直接初始化变量的好处在哪里,是否存在细微差别?
在某些情况下,存在一个潜在的显着差异。
实例初始值设定项在执行基类构造函数之前执行。 因此,如果基类构造函数调用在派生类中重写的任何虚方法,则该方法将看到差异。 通常这不应该是一个明显的区别,但是 – 因为在构造函数中调用虚方法几乎总是一个坏主意。
就清晰度而言,如果在声明点初始化变量,则很清楚该值不依赖于任何构造函数参数。 另一方面,将所有初始化保持在一起也有助于提高可读性,IMO。 我会尽可能地确保在可能的情况下,如果你有多个构造函数,它们都会委托给一个“主”构造函数来完成所有“实际”初始化 – 这意味着你只会将这些赋值放在一个地方。
用于演示差异的示例代码:
using System; class Base { public Base() { Console.WriteLine(ToString()); } } class Derived : Base { private int x = 5; private int y; public Derived() { y = 5; } public override string ToString() { return string.Format("x={0}, y={1}", x, y); } } class Test { static void Main() { // Prints x=5, y=0 new Derived(); } }
我不知道任何微妙的差异。 我通常喜欢在构造函数中放置所有初始化,因为我认为它使代码更具可读性。 但这更像是一种风格选择和个人偏好。 我没有听说过以某种方式certificate其合理性的技术理由。 我怀疑是否有任何性能影响。
静态和最终的常量是另一回事。 我初始化那些内联。
构造实例时,将在构造函数运行之前初始化在声明时初始化的任何变量。 如果您没有访问这些变量或在构造函数本身中使用它们的值,那么这两个方法之间没有function差异。
对于您的简单示例,它只是一种风格问题。
涉及inheritance时存在细微差别。 例如,字段初始化程序,执行顺序是派生类字段初始值设定项,基类字段初始值设定项,基类构造函数,派生类构造函数。
拿这个样本:
public class Program { public static void Main(string[] args) { new Derived(); } } public class Base { private int x = BaseInitializer(); public Base() { Console.WriteLine("Base ctor"); } private static int BaseInitializer() { Console.WriteLine("BaseInitializer"); return 0; } } public class Derived : Base { private int x = DerivedInitializer(); public Derived() : base() { Console.WriteLine("Derived ctor"); } private static int DerivedInitializer() { Console.WriteLine("DerivedInitializer"); return 0; } }
它打印:
假设我们在发布和优化版本下编译以下代码
namespace ConsoleApplication4 { public class Test1 { private int myIntToInitalize; public Test1() { myIntToInitalize = 10; } } public class Test2 { private int myIntToInitalize = 10; } static class Program { private static void Main() { } } }
IL类别测试指令1
.class public auto ansi beforefieldinit Test1 extends [mscorlib]System.Object { .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 L_0000: ldarg.0 L_0001: call instance void [mscorlib]System.Object::.ctor() L_0006: ldarg.0 L_0007: ldc.i4.s 10 L_0009: stfld int32 ConsoleApplication4.Test1::myIntToInitalize L_000e: ret } .field private int32 myIntToInitalize }
IL类别测试指令2
.class public auto ansi beforefieldinit Test2 extends [mscorlib]System.Object { .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 L_0000: ldarg.0 L_0001: ldc.i4.s 10 L_0003: stfld int32 ConsoleApplication4.Test2::myIntToInitalize L_0008: ldarg.0 L_0009: call instance void [mscorlib]System.Object::.ctor() L_000e: ret } .field private int32 myIntToInitalize }
很明显,两个类都有相同数量的IL指令,唯一的区别是,
在类Test1中调用:: ctor()之前初始化变量; 在类Test2中调用:: ctor()后初始化变量;
注意 :性能方面,Class都会执行相同的操作,因为它们具有相同数量和类型的IL指令,只是IL指令的执行顺序不同
public class Test { private int myIntToInitalize = 10; public Test() { } public Test(string x) { } } public class Test2 { private int myIntToInitalize; public Test2() { this.myIntToInitalize = 10; } public Test2(string x) { } }
在类Test1上,每个对象实例都将myIntToInitalize设置为10,但是当你调用需要1个参数的构造函数时,不会在类Test2上。
上述就是C#学习教程:变量初始化:直接还是在构造函数中?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/942397.html