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

时间:2011-06-21 19:51:58

标签: c# asp.net oop c#-2.0

如果我已将此类定义为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应用程序中第一次使用类来建模数据,而且我已经发现ViewView序列化似乎忽略了C#的by-reference性质,所以我想知道我可以期待的其他奇怪之处。例如,如果我定义了这个类(假设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]不再是同一个对象。

2 个答案:

答案 0 :(得分:3)

ASP.NET并不神奇。它并没有神奇地将C#编程语言(或任何其他语言)转换为了解Web开发(会话,请求等)的语言。

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


同样,没有魔力。与其他所有应用程序一样,静态的生命周期仅限于AppDomain的生命周期,其中包含静态类型的类型。

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

答案 1 :(得分:1)

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

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

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

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