c#基础知识Day2
第二章
1.属性
自动实现的属性:如果属性的get和set访问器中没有任何逻辑,就可以使用自动实现的属性。这种属性会自动实现后备成员变量。例如Public int Age{get;set},不需要声明private int age,编译器会自动创建他。
使用自动实现的属性,就不能再属性设置中验证属性的有效性。
2.构造函数
构造函数没有返回类型。
一般情况下,如果没有提供任何构造函数,编译器会在后台创建一个默认的构造函数。这是一个非常基本的构造函数,他只能把所有的成员字段初始化为标准的默认值。例如引用类型为空引用,数据类型为0,bool为false。
public class Student
{
private int ID;
private Student(int ID)
{
this.ID = ID;
}
}
这个例子没有为Student定义任何公有的或受保护的构造函数。这就使Student不能使用new运算符在外部代码中实例化(但可以在Student中编写一个公有静态属性或方法,以实例化该类)。这在以下两种情况下是有用的:
1.类仅用作某些静态成员或属性的容器,因此永远不会实例化他。
2.希望类仅通过调用某个静态成员函数来实例化(这就是所谓对象实例化的类工厂方法)。(这是什么意思??)
3.静态构造函数
C#的一个新特征也是可以给类编写无参数的静态构造函数。这种构造函数只执行一次。
编写静态构造函数的一个原因是,类有一些静态字段或属性,需要在第一次使用类之前,从外部资源中初始化这些静态字段和属性。
转载:https://www.cnblogs.com/jiagoushi/p/3775046.html
静态构造函数有哪些特点呢:
- 静态构造函数没有修饰符修饰(public,private),因为静态构造函数不是我们程序员调用的,是由.net 框架在合适的时机调用的。
- 静态构造函数没有参数,因为框架不可能知道我们需要在函数中添加什么参数,所以规定不能使用参数。
- 静态构造函数前面必须是static 关键字。如果不加这个关键字,那就是普通的构造函数了。
- 静态构造函数中不能实例化实例变量。(变量可以分为类级别和实例级别的变量,其中类级别的有static关键字修饰)。
- 静态函数的调用时机,是在类被实例化或者静态成员被调用的时候进行调用,并且是由.net框架来调用静态构造函数来初始化静态成员变量。
- 一个类中只能有一个静态构造函数。
- 无参数的静态构造函数和无参数的构造函数是可以并存的。因为他们一个属于类级别,一个属于实例级别,并不冲突。
- 静态构造函数只会被执行一次。并且是在特点5中的调用时机中进行调用。
- 就像如果没有在类中写构造函数,那么框架会为我们生成一个构造函数,那么如果我们在类中定义了静态变量,但是又没有定义静态构造函数,那么框架也会帮助我们来生成一个静态构造函数来让框架自身来调用。
例:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(A.strText);
Console.WriteLine(B.strText);
Console.Read();
}
}
public class A
{
public static string strText;
public string Text;
static A()
{
strText = "AAA";
}
public A()
{
Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
}
}
public class B : A
{
static B()
{
strText = "BBB";
}
public B()
{
Text = "BBBBBBBBBBBBBBBBB";
}
}
输出结果均为:AAA
我们来分析一下出现这个情况的原因所在,当显示A.strText的时候,因为strText是静态变量,所以框架会调用A的静态构造函数,此时strText的值为AAA.正确
当显示B.strText的时候,因为B继承自A,所以会首先调用A的静态构造函数,但是因为静态构造函数只会调用一次,所以不会调用A的静态构造函数,但是又因为strText属于类A,而不是B,所以B得静态构造函数不会执行,故输出的均为AAA。
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = new A();
Console.WriteLine(A.strText);
Console.WriteLine(B.strText);
Console.Read();
}
}
public class A
{
public static string strText;
public string Text;
static A()
{
strText = "AAA";
}
public A()
{
Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
}
}
public class B : A
{
static B()
{
strText = "BBB";
}
public B()
{
Text = "BBBBBBBBBBBBBBBBB";
}
}
请注意我在开始部分对类进行了实例化,那么此时的输出结果就是均为BBB。
为什么会有这样的情况出现呢,其实还是要从静态构造函数的调用时机入手。
首先我们实例化了B,此时会调用B的静态构造函数,但是因为strText是A的静态变量,所以首先会先调用A的静态构造函数将strText赋值为AAA,此时又会调用B的静态构造函数将strText赋值为BBB,所以此时strText的值应该为BBB,所以输出均为BBB。
总结:静态函数的调用时机,是在类被实例化或者静态成员被调用的时候进行调用,并且是由.net框架来调用静态构造函数来初始化静态成员变量。