【问题标题】:Static constructor called more than once多次调用静态构造函数
【发布时间】:2014-03-11 17:14:07
【问题描述】:
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() 中的静态构造函数会被调用一次,但是当我运行代码时,静态构造函数会被调用两次!!!!!!

当我删除这条线 &lt;T&gt; where T : IEnumerable&lt;int&gt; 一切正常(静态构造调用一次)?!!!!

【问题讨论】:

  • 静态是每个 type 的,泛型类型是您指定的每个不同 T 的类型。基本上,每个封闭的泛型本身就是一个类型,不管是从Test&lt;T&gt; 定义的。
  • Test&lt;List&lt;int&gt;&gt; != Test&lt;IList&lt;int&gt;&gt;
  • @AdamHouldsworth 您应该将其发布为答案。
  • 请张贴作为答案!
  • 完成了,但是我的手机键盘没有格式化在线代码的字符...

标签: c#


【解决方案1】:

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

基本上,每个封闭的泛型本身就是一个类型,无论是从泛型模板定义的。

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

【讨论】:

  • 我需要在静态构造函数中进行一些工作(这项工作应为 AppDomain 调用一次),但正如您在本例中所描述的,构造函数可能会被调用 X 次。我应该使用单例模式还是您有其他想法?
  • @BassamAlugili 无论如何,单身人士都会使用静态(或很可能会)。我可能会把它移到一个静态类中,其唯一目的是包含这个静态成员,然后移到其他东西上。
【解决方案2】:

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

泛型类型中的静态构造函数有很多用例,例如: https://stackoverflow.com/a/15706192/138304

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2012-09-24
    • 1970-01-01
    • 2013-03-05
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多