谨慎Asp.net中static变量的用法

.Net技术 2007-01-30 22:17:37 阅读925 评论11 字号:大中

谨慎Asp.net中static变量的用法

在.Net平台下进行CS软件开发时,我们经常遇到以后还要用到某些变量上次修改后的值,为了简单起见,很多人都习惯用static来定义这些变量,我也是。这样非常方便,下一次调用某个函数时该变量仍然保存的是处理过的值,直接拿来用就可以了。
    现在转入了BS软件开发,我们很自然地会沿用这种习惯。如在页面中统计某个按钮被按下的次数,先在类中OnClick事件的处理过程前定义一static变量times,则每次调用该按钮的OnClick事件时,令times增1即可,非常方便:

[C#]:
...
static int times=0;
...
private void Button1_Click(object sender,EventArgs e)
{
 times++;
 Label1.Text=times.ToString();
}
    在我们庆幸如此方便之余,就未曾意识到我们已经埋下了一棵难以察觉的定时炸弹。为什么哪?
    这还要从Asp.net的运行机制谈起。在CS模式软件开发过程中,我们通常不会关心应用程序是在哪里运行的,变量存放在哪里,客户端程序就运行在客户端,服务器端程序就运行在服务器端,一般情况下,二者除了数据库中的数据外基本没有其他共享的东西。所以这时客户端的用户大可放心的使用static变量,因为它们就存放在客户端程序中。
    于是我们就习惯的在做BS模式的页面时也用static变量,殊不知Asp.net中的static已不同于CS中的static。原因很简单,就是因为在Asp.net中所有的用户将使用同一个static变量。这就意味着每一个使用该页面的用户对该变量的操作将会影响到其他用户。就拿上面计数器的例子来说,假设times初试值为0,因为此时只有我们自己在使用这个页面,当然不会有什么问题,但如果有两个人同时连接到这个页面,如果A单击了Button1一次,则B刷新页面后Label1将显示1,如果B再单击Button1一次,则times变成2,两个人刷新页面后就出现问题了:A和B都会说,我明明只单击了Button1一次,怎么Label1就显示我单击了两次哪?——这就是因为两个人共用的是服务器上同一个times,任何一个人对times的操作都会在使用该页面的他人的浏览器中表现出来。问题就出在这里。
    怎么办哪?还好,除了传统的Asp中的Session对象外,Asp.net提供了一个更好的ViewState对象。ViewState对象用来保存页面中的各种变量,甚至是对象。使用方法和HashTable类似,只要用变量名称做索引,如ViewState["Var"],就可以用存取变量Var的值,而不管Var是普通变量,还是对象,甚至是内存中的一张DataTable,太方便了。为什么可以用ViewState而不能用static变量哪?原因就是服务器端会为每个连接到该页面的用户分别建立一个ViewState,所以ViewState相当于页面级的Session。这下我们可以放心地使用ViewState来存取需要暂存的变量和对象了。
    ViewState的用法很简单,如下所示:
    1、保存变量到ViewState中:
       ViewState["times"]=times;//存放普通变量times
       ViewState["Orders"]=dtOrders;//存放DataTable型对象dtOrders
    2、读出ViewState中的值:
       times=(int)ViewState["times"];
       dtOrders=(DataTable)ViewState["Orders"];
    看见了吧?就如此简单!有的朋友会问读出变量的值时为什么要进行强制类型转换?这是因为当变量(不管是int型的普通变量times,还是DataTable型的对象dtOrders)被存放到ViewState中后,ViewState可不管你是普通变量还是对象,统统按Object来对待。所以当我们取出存放在ViewState中的东西时,一定要转换成相应的类型,否则就会报错。而这一操作不用在用ViewState保存变量时进行,系统会自动转换。(注意ViewState括号中的字符串只是为了标识不同变量的索引,用不着非要和变量同名)所以上面计数器的代码应该这样写才好:
       ...
       ViewState["times"]=0;
       ...
       private void Button1_Click(object sender,EventArgs e)
       {
           int times=(int)ViewState["times"];
           times++;
           ViewState["times"]=times;
           Label1.Text=times.ToString();
        }
    一般情况向下,将要保存到ViewState中的对象(或变量)用属性的形式来实现会更方便。如对于上述的计数器times,可以这样处理:
    ...
    private int times
    {
        get
        {
            return (int)ViewState["times"];
        }
        set
        {
            ViewState["times"]=value;
        }
    }
    ...
    private void Button1_Click(object sender,EventArgs e)
    {
        times++;
        Label1.Text=times.ToString();
    }
    ...
    在这里times将当作私有属性来操作,是不是非常方便?
    那是不是说static型变量就没用了哪?当然不是!在C#中用static声明的类不用实例化直接使用。正是由于所有用户共享服务器端的同一个static变量,所以可以用static型对象来存取一些公用的处理模块,比如类型转换、变量验证等工作。所以要根据具体情况而定。
    还有一点需要注意:如果在页面中多个过程要共享一个对象或变量,我们在页面类的开始部分定义一个页面级的全局变量是不行的,static本来可以,但上面说了这种类型的变量不安全,所以这时就可以用ViewState。
    好了,这下我们可以放心的暂存某些变量或对象了。

谨慎Asp.net中static变量的用法相关推荐

  1. ASP.NET中application对象的用法(面试题)

    ASP.NET中application对象的用法 本文导读:Application对象是HttpApplicationState类的一个实例,Application状态是整个应用程序全局的.Appli ...

  2. asp.net 页面static变量问题

    下面引用 http://www.cnblogs.com/meyer/archive/2004/04/27/7846.html 在C#中,static变量表示该变量属于类,而不是类的实例.可以说是该类的 ...

  3. c++中static变量的存储duration

    c++中static变量的存储duration static是c++中一个常见的关键字,当修饰全局变量和局部变量时会有不同的效果,同时变量声明初始化与否对生成的二进制文件也有影响. 写了一小段代码测试 ...

  4. 类中static变量和成员变量

    类中static变量和普通变量的区别(一便解释了摘要中的内容) ​ 要理解标题,我们首先来看下static变量本身的特殊之处,即它存储在全局数据区.在类中的static变量也是如此. C++的内存分布 ...

  5. Java多线程中static变量的使用

    Java中 没处理好同步 导致两个线程同时为一个static变量赋值 会导致什么后果? Java中 没处理好同步 导致两个线程同时为一个static变量赋值 会导致什么后果?仅仅是多耗资源还是会引发异 ...

  6. Java中static变量作用和用法详解

    static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...

  7. java中静态变量的作用_Java中static变量作用和用法详解

    static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...

  8. c++中static的全部用法

    要理解static,就必须要先理解另一个与之相对的关键字,很多人可能都还不知道有这个关键字,那就是auto,其实我们通常声明的不用static修饰的变量,都是auto的,因为它是默认的,就象short ...

  9. Java中static作用及用法详解

    1.1概述: static是静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存 ...

最新文章

  1. lnmp mysql 哪个好_lamp与lnmp的选择
  2. BZOJ4105 THUSC2015平方运算(线段树)
  3. oracle+字段+virtual,Oracle 11g新特性之--虚拟列(Virtual Column)
  4. FZU-2218 Simple String Problem(状态压缩DP)
  5. 中国.NET域名注册量近55万个 稳居全球第三位
  6. 一个用理性设计的搞笑游戏
  7. mysql 热备 windows_windows下mysql热备
  8. python怎么读取pdf文件_Python解析并读取PDF文件内容的方法
  9. mysql 创建唯一索引_Mysql普通索引和唯一索引的选择分析
  10. 【STM32】【STM32CubeMX】STM32CubeMX的使用之六:定时器配置输出PWM,实现变色呼吸灯
  11. STM8单片机ADC连续扫描模式
  12. Oracle中split功能的实现
  13. 无线网络,把我整惨了。求助各位了。
  14. Oracle项目管理系统之供应商筛选及资格预审
  15. 层次分析法详解(matlab)
  16. cad计算机快捷键设置,小U讲解完整版电脑CAD快捷键大全
  17. git bash安装SDKman遇到需要安装zip的问题
  18. 2020哈工程上岸初复试经验
  19. 后端做app连续会员包月功能 -- IOS连续订阅 支付宝周期扣款
  20. 明日方舟抽卡模拟器wiki_明日方舟抽卡模拟器

热门文章

  1. 25美元 Linux PC 'Raspberry Pi' 一月上市
  2. ASP.NET MVC: 使用自定义 ModelBinder 过滤敏感信息
  3. hdu 4533(树状数组区间更新+单点查询)
  4. NYOJ 679 The Weight of Tree 搜索+dp+邻接表
  5. 网络流最大流Edmonds-Karp算法(模板)
  6. Eclipse显示内存占用
  7. Python正则表达式指南
  8. typedefnbsp;struct与struct的区别
  9. Linq to XML的练习
  10. Go 语言 练习 聊天室 01