静态构造函数不止一次被调用

时间:2014-03-11 17:14:08

标签: c#

using System;

namespace ConsoleApplication15
{
  using System.Collections.Generic;
  using System.Threading;

  public static class Program
  {
    static void Main(string[] args)
    {
      var test1 = new Test<List<int>>();
      var t = new Thread(Tester);
      t.Start();

      var test2 = new Test<List<int>>();
      var test3 = new Test<List<int>>();
      var test4 = new Test<List<int>>();
      var test5 = new Test<List<int>>();


      test1.Do();
      test2.Do();
      test3.Do();
      test4.Do();
      test5.Do();
    }

    private static void Tester()
    {
      var test5 = new Test<IList<int>>();
      test5.Do();
    }
  }

  public class Test<T> where T : IEnumerable<int>
  {

    private static Something something;

    static Test()
    {
      Console.WriteLine("IM  static created ");

      something = new Something();
      Console.WriteLine(something.ToString());
    }

    public Test()
    {
      Console.WriteLine("IM  created ");
    }

    public void Do()
    {
      Console.WriteLine("Do something! ");
    }
  }

  public class Something
  {
    public Something()
    {
      Console.WriteLine("Create something");
    }
  }
}

当我运行上面的代码时,我已经意识到 static Test() 中的静态构造将被调用一次,但是当我运行代码时,静态构造被调用两次! !!

当我删除此行<T> where T : IEnumerable<int>时,一切正常(静态construcor称为一次)?!!!!

This is the breakpoint for the first call This is the breakpoint for the second call

2 个答案:

答案 0 :(得分:4)

静态是每种类型,泛型类型为您指定的每个不同T创建一个新类型。

基本上,每个封闭的泛型都是一种类型,无论是从通用模板定义的。

这是静态成员的常见问题。

答案 1 :(得分:1)

在C#中,泛型类型的特定参数化实际上是唯一类型。这是保留泛型类型信息作为运行时的一部分的优点,而不是像Java那样在编译过程中删除泛型类型信息的语言。

泛型构造函数有许多用例,例如: https://stackoverflow.com/a/15706192/138304

依赖于泛型类型的静态构造函数为每个封闭的泛型类型运行一次的另一种情况是像EqualityComparer<T>这样的类,其中静态构造函数可用于为每个类型初始化Default属性输入T