再谈CLR:构造之谜

这一篇谈谈类型构造的问题。主要针对构造器这个层面进行一些探讨。

1. 有哪几种构造器

  • 默认构造器(无参数)
  • 自定义构造器(有参数)
  • 静态构造器

2.何时调用构造器

  • 通过new关键字创建实例的时候
  • 通过createInstance方法创建实例的时候
  • 静态构造器是不能调用的,是由CLR调用,而且它只被调用一次(Assembly级别)

3. 特殊问题

  • 默认构造器默认有一个实现,当然没有任何代码

image

  • 如果我们编写了自定义构造器,此时默认构造器就不会自动产生一个,除非显式定义。(这个行为有点怪异)
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]
            };
        }
    }
}

image

原文地址:https://www.cnblogs.com/chenxizhang/p/1691105.html