C#构造函数总结
构造函数
构造函数分为:实例构造函数,静态构造函数,私有构造函数。
1、构造函数的名字与类名相同。
2、使⽤ new 表达式创建类的对象或者结构(例如int)时,会调⽤其构造函数。并且通常初始化新对象的数据成员。
3、除⾮类是静态的,否则会为没有构造函数的类,⾃动⽣成⼀个默认构造函数,并使⽤默认值来初始化对象字段。
4、构造函数可以有参数,可以以多态的形式存在多个构造函数。
例:
class CoOrds
{
public int x, y;
// 实例构造函数(默认构造函数)
public CoOrds()
{
x = 0;
y = 0;
}
// 具有两个参数的构造函数
public CoOrds(int x, int y)
{
this.x = x;
this.y = y;
}
// 重写toString⽅法
public override string ToString()
{
return (String.Format("({0},{1})", x, y));
}
static void Main(string[] args)
{
CoOrds p1 = new CoOrds();
CoOrds p2 = new CoOrds(5, 3);
// 使⽤重写ToString⽅法显⽰结果
Console.WriteLine("CoOrds #1 at {0}", p1);
Console.WriteLine("CoOrds #2 at {0}", p2);
Console.ReadKey();
}
}
/* Output:
CoOrds #1 at (0,0)
CoOrds #2 at (5,3)
*/
其中CoOrds()是构造函数,诸如此类不带参数的构造函数称为“默认构造函数”。
CoOrds(int x, int y)同样也是构造函数,构造函数可以有参数,允许多态。
静态构造函数具有以下属性:
静态构造函数不使⽤访问修饰符或不具有参数。
在创建第⼀个实例或引⽤任何静态成员之前,将⾃动调⽤静态构造函数以初始化类。
不能直接调⽤静态构造函数。
⽤户⽆法控制在程序中执⾏静态构造函数的时间。
静态构造函数的⼀种典型⽤法是在类使⽤⽇志⽂件且将构造函数⽤于将条⽬写⼊到此⽂件中时使⽤。
静态构造函数对于创建⾮托管代码的包装类也⾮常有⽤,这种情况下构造函数可调⽤LoadLibrary⽅法。
如果静态构造函数引发异常,运⾏时将不会再次调⽤该函数,并且类型在程序运⾏所在的应⽤程序域的⽣存期内将保持未初始化。
构造函数与静态构造函数:
class TestClass
{
public static int x = 0;
//构造函数
TestClass()
{
x = 1;
}
//静态构造函数
static TestClass()
{
//第⼆步,执⾏x = 2
x = 2;
}
//第⼀步,程序⼊⼝Main最先执⾏。然后执⾏public static int x = 0 接着执⾏静态构造函数。
public static void Main(string[] args)
{
Console.WriteLine("x:{0}", x); //打印,x = 2
TestClass Test = new TestClass();//第三步执⾏构造函数,此时x = 1
Console.WriteLine("x:{0}", x); //打印 x = 1
Console.Read();
}
}
Main是程序⼊⼝,当执⾏Main的时候,最先执⾏public static int x = 0
接着执⾏静态构造函数,此时 x = 2
然后执⾏Main函数⾥⾯的内容,打印 x,此时 x = 2
初始化TestClass,然后会执⾏构造函数,此时 x = 1
打印 x = 1
那么,在调⽤某类的静态函数时真正的执⾏顺序:
1、静态变量 > 静态构造函数 > 静态函数
2、静态变量 > 静态构造函数 > 构造函数
C#⾼效编程改进C#代码的50个⾏之有效的办法(第2版)⾥说到这样⼀段话:
类型实例的完整过程。你需要理解这些操作的顺序,以及对象的默认初始化操作。你要保证在构造的过程中对每个成员变量仅初始化⼀次。实现这⼀点最好的⽅法就是,尽可能的早地进⾏初始化。
下⾯就是创建某个类型的第⼀个实例时,所进⾏的操作顺序为:
(1)静态变量设置为0
(2)执⾏静态变量初始化器
(3)执⾏基类的静态构造函数
(4)执⾏静态构造函数
(5)实例变量设置为0
(6)执⾏衯变量初始化器
(7)执⾏基类中合适的实例构造函数
(8)执⾏实例构造函数
同样类型的第⼆个以及以后的实例将从第5步开始执⾏,因为类的构造器仅会执⾏⼀次。此外,第6步和第7步将被优化,以便构造函数初始化器使编译器移除重复的指令。
练习题:(core项⽬下,答案不同)
public class A
{
public static readonly int x;
static A()
{
x = B.y + 1;
}writeline函数
}
public class B
{
public static int y = A.x + 1;
public static void Main(string[] args)
{
Console.WriteLine("x:{0},y:{1}。", A.x, y);
Console.ReadLine();
}
}
下⾯公布答案:
public class A
{
public static readonly int x;
static A()
{
//第⼆步,调⽤B.y,此处B.y = 0,因为int类型在初始化阶段,会给赋默认值,默认值为0。最后x = 0 + 1(返回给第⼀步)
x = B.y + 1;
}
}
public class B
{
//第⼀步,调⽤A.x,然后执⾏类A的静态构造函数,等待返回(第⼆步返回的A.x = 1,所以y = 1 + 1)
public static int y = A.x + 1;
public static void Main(string[] args)
{
//第三步,A.x = 1,y = 2。
Console.WriteLine("x:{0},y:{1}。", A.x, y);
Console.ReadLine();
}
}
练习题答案
详细解答:
1、⾸先,每⼀个项⽬有且只能有⼀个静态类的Main函数作为⼊⼝函数。⽽⼊⼝函数是最先执⾏的。
2、由于Main函数在B类⾥⾯,⾸先会初始化B类。⽽类的初始化顺序是:类⾥的静态变量,然后执⾏静态构造函数。
3、运⾏起先执⾏ public static int y = A.x + 1 这个,执⾏的时候,会先把 y 初始化为0,然后计算 y 的值。
4、计算 y 的值的时候,调⽤了 A 的静态变量 x 。所以会先初始化A。
5、初始化A时⾸先去执⾏ public static readonly int x ,先把 x 初始化为0。
6、然后执⾏A的静态构造函数 x = B.y + 1 此时 y 已经初始化为0了。
7、计算得到 x = 1。然后回到 public static int y = A.x + 1 得到 y = 2。
8、然后再执⾏Main函数的内容。得出结果x=1,y=2
补充:⼩鹏Y提出了 core 项⽬下得出的答案有出⼊。⾮常感谢他!以下是 core 项⽬的⾓度
在第⼆步计算 x = B.y + 1,B.y 的值是1,不是0。所以在计算 x = B.y + 1 的时候,x = 2。
最后的结果变成:A.x = 2,y = 1
具体为何这样,还不清楚,此篇⽂章⽬前只考虑⾮ core 项⽬的情况。
私有构造函数是⼀种特殊的实例构造函数。它通常⽤于只包含静态成员的类中。如果类具有⼀个或多个私有构造函数⽽没有公共构造函数,则其他类(除嵌套类外)⽆法创建该类的实例。
public class PrivateConstructor
{
private PrivateConstructor()
{
//PrivateTest a = new PrivateTest(); //注释打开会报错,错误信息:不可访问,因为它受保护级别限制。因为私有构造函数⽆法在类的外⾯实例化。
}
public class PrivateTest
{
int i;
private PrivateTest()
{
i = 3;
}
static void Main(string[] args)
{
PrivateConstructor t = new PrivateConstructor(); //嵌套类允许实例化。
PrivateTest p = new PrivateTest(); //类的内部允许实例化。
Console.WriteLine("i:{0}", p.i); //结果:i:3
Console.Read();
}
}
}
声明空构造函数可阻⽌⾃动⽣成默认构造函数。请注意,如果不对构造函数使⽤访问修饰符,则在默认情况下它仍为私有构造函数。但是,通常会显式地使⽤ private 修饰符来清楚地表明该类不能被实例化。
实例:
其中单例模式就⽤到了私有构造函数的特性来保证类不会被实例化。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。