【问题标题】:Static Field Life Time in Base class基类中的静态字段生命周期
【发布时间】:2011-12-22 02:20:39
【问题描述】:

我有一个带有单个静态字段的简单基类。我有许多从这个基类派生的类。当我创建派生类时,它会调用基类静态 ctor 来初始化静态字段(按预期工作)。问题是当我创建另一个继承自同一个基的派生类时,基中的静态字段仍然为空,为什么????它是由我实例化的第一个类初始化的。

基类中的静态字段不应该具有全局分配并且对所有派生类可见(即共享)吗?

我的模特:

class Base<T>
{

 protected static object s_field = null;

 static Base { s_field = new object(); }
}

class Derived1<T> : Base<T>
{

}

class Derived2<T> : Base<T>
{

}

// ... later in the program

Derived1<int> instance1 = new Derived1<int>(); // initializes static field (s_field in base class) for all derived types

Derived2<double> instance2 = new Derived2<double>(); // the static field is null

(我可以通过调试器看到这一点,但它应该不是已经被上一行初始化了吗??)

【问题讨论】:

  • 请不要在标题前加上“C# .net -”。这就是标签的用途。
  • @ActiveX 这是您的程序可以执行的唯一行吗?是否有可能在instance1 的实例化之间的某个地方将静态字段设置为空,此时instance2 对象似乎具有空值?这可以通过同时比较两个对象来验证,如果一个为空而另一个不是,那么你已经遗漏了一些东西。
  • 应该而且确实如此。我刚刚尝试了您的 sn-p 并且静态字段不为空。因此,无论您在观察什么,其原因都不在此处发布的代码中
  • 这里还有更多内容,因为这些类型被 Caslte Active Record 库使用,但我认为它不会在初始化期间使我的静态字段无效。让我尝试在框架之外创建我的对象。我会尽快报告。
  • 我意识到我的错误了!哇,基类实际上是一个模板类:Base。当我创建像这样 new Derived(), new Derived(), new Derived() 这样的基础对象时,这些是完全不同的类型,因此静态字段规则不同,我的理解是静态字段将分配给 T 类型的家庭。我对此的理解是否正确?请确认。

标签: c# .net static memory-management field


【解决方案1】:

由于您更改了代码,我相信您需要了解泛型在 .NET 中的工作原理。

泛型中的静态行为与正常情况下有些不同。对于您提供的每个唯一的开放类型 T,基类都维护唯一的静态成员值。

你通过 Derived 为同一个基类创建另一个开放类型 double 的实例,然后你就会明白我在说什么。

这里有一个示例代码可以更清楚地演示:

public class Base<T>
    {
        public static string str = null;

        static Base()
        {
            str = "hello";

            Console.WriteLine("Ctor cald");
        }
    }

    public class Derived1<T> : Base<T>{}
    public class Derived2<T> : Base<T> { }

    public partial class Program
    {
         public static void Main()
        {
            Derived1<int> derv = new Derived1<int>();
            Derived2<double> derv2 = new Derived2<double>();
            Derived2<double> derv3 = new Derived2<double>();


            Console.ReadKey();
        }      
    }  

在这里,您只会看到对静态 Ctor 的 2 次调用。

【讨论】:

    【解决方案2】:

    我意识到我的错误!哇,基类实际上是一个模板类:Base&lt;T&gt;。当我创建像这样new Derived&lt;int&gt;()new Derived&lt;double&gt;()new Derived&lt;object&gt;() 这样的基础对象时,这些是完全不同的类型,因此静态字段规则不同,我的理解是静态字段将分配给类型 T 的系列. 我已经更正了上面的示例以反映这一点(在最初的帖子中)。

    【讨论】:

    • 仅供参考,您需要引用尖括号。选择代码并按 Control-K。我已经为你完成了。
    【解决方案3】:

    当您将泛型放入图片时,整个问题都会发生变化。您对静态成员继承的理解在没有泛型的情况下按预期工作,当泛型存在时,这个概念仍然有效,但泛型在运行时创建不同的类型除外。 Base&lt;int&gt;Derived1&lt;int&gt; 共享相同的静态成员,而 Derived1&lt;decimal&gt; 在运行时与 Base&lt;int&gt; 的类型不同,不共享静态成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-06
      • 2021-01-03
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 2018-02-12
      相关资源
      最近更新 更多