Csharp/C#教程:变量初始化:直接还是在构造函数中?分享


变量初始化:直接还是在构造函数中?

可能重复:
最佳实践:在构造函数或声明中初始化类字段?

大多数时候,我看到了像这样初始化变量的方法

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

(0)
上一篇 2021年11月13日
下一篇 2021年11月13日

精彩推荐