这一篇谈谈类型构造的问题。主要针对构造器这个层面进行一些探讨。
1. 有哪几种构造器
- 默认构造器(无参数)
- 自定义构造器(有参数)
- 静态构造器
2.何时调用构造器
- 通过new关键字创建实例的时候
- 通过createInstance方法创建实例的时候
- 静态构造器是不能调用的,是由CLR调用,而且它只被调用一次(Assembly级别)
3. 特殊问题
- 默认构造器默认有一个实现,当然没有任何代码
- 如果我们编写了自定义构造器,此时默认构造器就不会自动产生一个,除非显式定义。(这个行为有点怪异)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Title = "构造之谜";
//1.通过new的方式进行构造
Employee emp = new Employee() { FirstName = "ares", LastName = "chen" };
Console.WriteLine(emp);
//如果没有默认构造器,则编译出错
Employee emp1 = new Employee("ares", "chen");
Console.WriteLine(emp1);
//2.通过CreateInstance方式进行构造,这是调用默认构造器
Employee emp2 = Assembly.GetExecutingAssembly().CreateInstance(typeof(Employee).FullName) as Employee;
//如果没有默认构造器,则编译不出错,而运行出错,因为CreateInstance方法是调用默认构造器的
emp2.FirstName = "ares";
emp2.LastName = "chen";
Console.WriteLine(emp2);
//3.通过带参数的CreateInstance方式构造,这是调用自定义构造器
Employee emp3 = Assembly.GetExecutingAssembly().CreateInstance(
typeof(Employee).FullName,
true, BindingFlags.CreateInstance,
null,
new object[] { "ares", "chen" },
Thread.CurrentThread.CurrentCulture,
null) as Employee;
Console.WriteLine(emp3);
//4.通过隐式操作符来构造
Employee emp4 = "ares,chen";
Console.WriteLine(emp4);
Console.Read();
}
}
class Employee {
static Employee()
{
//静态构造器只会被调用一次,而且永远会被调用
Console.WriteLine("静态构造器在工作");
//如果类型的静态成员需要经过复杂的逻辑才能初始化,那么应该在静态构造器里面对其进行处理
}
public Employee()
{
//这个构造器默认就是有的,但如果有自定义构造器,则需要显式地定义该构造器
Console.WriteLine("默认构造器在工作");
}
public Employee(string firstName, string lastName) {
//如果编写了自定义构造器,默认情况下居然会把默认构造器禁用掉。必须显式地定义默认构造器
FirstName = firstName;
LastName = lastName;
Console.WriteLine("自定义构造器在工作");
}
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return string.Format("Employee:{0},{1}", FirstName, LastName);
}
public static implicit operator Employee(string employee) {
return new Employee()
{
FirstName = employee.Split(',')[0],
LastName = employee.Split(',')[1]
};
}
}
}