ASP中的静态类变量行为.NET 2.0

本文关键字:NET 类变量 静态 静态类 ASP | 更新日期: 2023-09-27 17:59:45

如果我已经将这个类定义为ASP中应用程序的一部分。NET 2.0:

public class Foo
{
   private static int _seed = 100;
   private static object myLock = new object();
   public Foo()
   {
      lock (myLock)
      {
         this.MyInt = _seed;
         _seed++;
      }
   }
   public int MyInt {get; set;}
}

(编辑:更新以说明回答中指出的线程安全问题)

该静态成员将如何表现?它是从100开始,并为每个会话单独递增,还是为每个页面刷新单独递增,或者是全局的。。。?

注意:我之所以这么问,是因为我第一次在ASP中使用类来建模数据。NET应用程序,我已经发现C#的引用性质似乎被ViewState序列化忽略了,所以我想知道我还能期待什么其他奇怪的事情。例如,如果我定义了这个类(假设Bar是另一个类):

public class OtherFoo
{
   public List<Bar> Bars {get; set;}
}

我在我的页面上这样做:

OtherFoo _myFoo = new OtherFoo();
//Code here to instantiate the list member and add some instances of Bar
Bar b = _myFoo.Bars[0];
ViewState["myFoo"] = _myFoo; //Assume both are [Serializable]
ViewState["myBar"] = b;

当我在下一次回发时将它们从ViewState中取出时,b_myFoo.Bars[0]不再是同一个对象。

ASP中的静态类变量行为.NET 2.0

ASP。NET不是魔法。它不会神奇地将C#编程语言(或任何其他语言)变成一种了解web开发(会话、请求等)的语言。

您的代码将像在任何其他类型的应用程序中一样执行,此外,它可以由多个线程同时调用(因此使用"++"是不安全的)。


再说一遍,没有魔法。就像其他应用程序一样,静态的生存期被限制为加载包含静态的类型的AppDomain的生存期。

ASP中的AppDomain。NET应用程序是在第一次访问应用程序时创建的(除非IIS设置强制它预启动),并且仅在特定时间结束,例如bin文件夹中的程序集更改、web.config更改,或者IIS设置指示需要回收AppPool时。

每次调用构造函数时,它都会增加种子。请注意,这可能发生在多个线程中,因此您最好确保它是线程安全的。

反序列化将导致调用(默认)构造函数。如果将其序列化为ViewState,则ASP。NET将在回发时反序列化对象,从而调用构造函数。

请注意,C#语言和asp.net框架在另一个层面上。该框架(主要)是用C#编写的,它将在幕后为您做很多事情,但它仍然遵循语言和运行时的规则。

序列化只不过是将对象(或对象图)的信息编码到流中。如果反序列化它,您将返回相同的信息,但它与您开始使用的对象不同。同样,这并不是魔术,您可以使用属性和反射编写自己的序列化库。