关于ASP.NET中的静态变量问题?
我是用了“动软.NET代码生成器”生成的一系列简单三层架构代码(MODEL+DAL+BLL+WEB),我是要做一个小型企业网站,
我在Web层用到了大量静态变量,例如:网站的名称、域名、logo等等,在Web层中都封装到一个类的 静态属性 里去了,
我不知道这样做是否妥当!
请问,使用静态成员的坏处及静态成员在WebForm中和WinForm中有什么不同?谢谢了!

解决方案 »

  1.   

    这是这个类的代码!using System;
    using System.Collections.Generic;
    using System.Web;using System.Text.RegularExpressions;namespace IdealWebSite
    {
        public class  Company
        {
            private static IdealWebSite.BLL.Company _cm = new IdealWebSite.BLL.Company();
            private static IdealWebSite.Model.Company _company = new IdealWebSite.Model.Company();
            private static Regex _rx;        static  Company()
            {
                _company = _cm.GetModel(1);
            }        #region 属性
            /// <summary>
            /// 只读,获取公司编号
            /// </summary>
            public static int CompanyID
            {
                get { return _company.CompanyID; }
            }        /// <summary>
            /// 地址
            /// </summary>
            public static string CompanyAddress
            {
                get { return _company.CompanyAddress; }
                set { _company.CompanyAddress = value; }
            }        /// <summary>
            /// 版权
            /// </summary>
            public static string ComCopyright
            {
                get { return _company.CompanyCopyright; }
                set { _company.CompanyCopyright = value; }
            }        /// <summary>
            /// 域名
            /// </summary>
            public static string CompanyDomain
            {
                get { return _company.CompanyDomain; }
                set 
                {
                    _rx = new Regex(@"^([a-z0-9\-]{1,}\.)?[a-z0-9\-]{2,}\.([a-z0-9\-]{1,}\.)?[a-z0-9]{2,}$/i)");
                    if (_rx.Match(value).Success)
                    {
                        _company.CompanyDomain = value;
                    }
                }
            }        /// <summary>
            /// Fax
            /// </summary>
            public static string CompanyFax
            {
                get { return _company.CompanyFax; }
                set { _company.CompanyFax = value; }
            }        /// <summary>
            /// ICP
            /// </summary>
            public static string CompanyICP
            {
                get { return _company.CompanyICP; }
                set { _company.CompanyICP = value; }
            }        /// <summary>
            /// Logo
            /// </summary>
            public static string CompanyLogo
            {
                get { return _company.CompanyLogo; }
                set { _company.CompanyLogo = value; }
            }        /// <summary>
            /// Mail
            /// </summary>
            public static string CompanyMail
            {
                get { return _company.CompanyMail; }
                set 
                {
                    _rx=new Regex(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* ");
                    if (_rx.Match(value).Success)
                    {
                        _company.CompanyMail = value;
                    }
                }
            }        /// <summary>
            /// Name
            /// </summary>
            public static string CompanyName
            {
                get { return _company.CompanyName; }
                set { _company.CompanyName = value; }
            }        /// <summary>
            /// Tel
            /// </summary>
            public static string CompanyTel
            {
                get { return _company.CompanyTel; }
                set 
                {
                    _rx = new Regex(@"(\d+-)?(\d{4}-?\d{7}|\d{3}-?\d{8}|^\d{7,8})(-\d+)?");
                    if (_rx.Match(value).Success)
                    {
                        _company.CompanyTel = value;
                    }
                }
            }
            #endregion        #region 方法
            /// <summary>
            /// 更新到数据库
            /// </summary>
            public static void Update()
            {
                _cm.Update(_company);
            }
            #endregion
        }
    }
      

  2.   

    静态变量没什么不好,为什么会有讨论静态变量的根本原因是:静态变量的回收问题。静态变量是GC的根。按照GC的回收规则,根是不会被回收的。
    静态变量最大的问题应该就是内存释放的问题,这个问题在大型的项目中尤为明显,而且一般情况下都是不被察觉的情况下被滥用。
    比如:一个静态变量隐式的引用了this,这种情况下可能会导致this不会被释放,this可能是一个page也可能是一个其他对象,这将导致连锁反映,所有和this有引用关系的对象都会被Hold住,在垃圾回收的时候这些对象将不会被释放。
    静态属性没有任何问题,静态方法也没有,这些属性和方法是在类型对应的方法表中。但是静态变量也不是不能使用,只是使用的时候要格外的小心,其方便性不言而喻。WebForm和WinForm里面静态变量的内存布局是一样的(都在托管堆上),所以他们没有本质的区别,只是应用的场景不同而已。分析你的例子:private static IdealWebSite.BLL.Company _cm = new IdealWebSite.BLL.Company();
    private static IdealWebSite.Model.Company _company = new IdealWebSite.Model.Company();
    private static Regex _rx;
     
    这些将对象是根,不会被释放,如果你的程序中有引用这些对象的地方要格外小心。
      

  3.   

    这个类 应该放在MODEL层,其他层都要引用这个层,就可访问了,一般都这样做,这样就合理了。
      

  4.   

    这个类 应该放在MODEL层,其他层都要引用这个层,就可访问了,一般都这样做,这样就合理了。
      

  5.   

    @cuike519谢谢!“一个静态变量隐式的引用了this”         这句不大明白!
    private static IdealWebSite.BLL.Company _cm = new IdealWebSite.BLL.Company();
    private static IdealWebSite.Model.Company _company = new IdealWebSite.Model.Company();
    private static Regex _rx; 
    声明为private就是不让类外部引用!
      

  6.   


    汗  LZ 自己对基础知识 认识不深
    静态变量的  认识 要从CLR开始 首先CLR会给默认的 类成员赋值  比如 int i; i默认=0
    但是 静态变量 也是 在 第一个  实例出现之前赋值的,而且 只会赋值一次 .他不输入 实例成员
    属于类成员 ,所以 可以直接 通过 类.变量 来访问 ,避免了其他语言中的 全局变量 
    静态变量的好处 就在于 他仍然 输入 类,作用域 还是在类中,一旦他的被引用的 成员全部没有引用了 就被CLR 回收了
    这样的话  ,申明 static  比如网站名,对于 这些不要求 线程安全的 变量 直接 申请就好了
      

  7.   

    关于this我是举个例子,在实际的项目中我遇到过这种情况。我所说的隐式含义是说:比如在一个页面实例方法中使用了这个静态变量,即使你没有写this,但是实际上这里有个this存在,这种情况可能会出现在事件绑定的时候。声明为私有的确实不会被外部访问,我只是说明问题,提醒你在使用的时候要格外的注意,如果你的项目很小,这个问题并不凸显。知道所以然你在使用的时候就会避免一些已知的问题。根是不会被回收的,这是GC垃圾回收的起点,否则GC无法判断这个对象是不是垃圾,比如:栈上的对象也是根,寄存器里面的也是根。垃圾回收是不可预测的,必须要有一个规则来确定哪些是垃圾哪些不是垃圾呵呵,扯得有点远了
      

  8.   

    @cuike519 受教了!
    很是感谢!那么说我这样做是可行的,不过要小心使用了?
      

  9.   

    那么我这里的静态成员是在什么时候产生和什么时间灭亡的??
    这个代码放在IIS上运行的话,静态成员是在第一个用户访问后一直存在还是??
      

  10.   

    呵呵,这个问题,好像是一个无需技巧来判断的问题似的。我们使用放在asp.net应用程序的Cache中的变量来做个对比,缓存对象可以在设置CacheDependency,于是可以依赖数据库、文件、其它Cache缓存对象的改变而过期(下一次重新从数据库中Get),而且Cache机制本身可以在物理内存不足时自动地清理一批缓存对象(即使它根本没有过期)。可见Cache是为了大量使用内存而不用过多担心内存管理问题而设计的,Cache更适合那些仅需要缓存几分钟就已经令人满意的对象。不能把过多的根本不读取的数据随便放入,例如不应该将一类数据全都从数据库读出放入内存,因为当数据库修改了反而造成内存的数据被频繁丢弃,我们可以以查询时使用的SQL为缓存键仅仅缓存一页数据。对比之下,static变量的概念就太简单了。static变量用于保存比asp.net缓存对象更频繁读取的少量全局信息是合适的。如果能够将static的变量控制在几M空间以下,对于WebForm应用似乎就也是所谓的完全可以的。抛开所占空间的问题,剩下的就是逻辑一致性问题。其实如果你对于关键的数据的一致性有疑问,这往往仅凭概念看不出来会有哪些方面的影响。你可以查找使用了目标变量的一些常用的方法写入断言,并且在Debug模式下经常运行最终的程序,这样可以在平常运行程序时及时提前准确地定位问题。
      

  11.   

    静态方法和静态属性函数在方法表里面,它的生命周期和类是一样的==》这个代码放在IIS上运行的话,静态成员是在第一个用户访问后一直存在还是??
    一直存在,直到应用程序结束
      

  12.   

    如果设计一些非常具体的架构,可能稍显复杂。而这个问题则不涉及任何具体的架构,所谓内涵小而外延大。在空间方面,统计所有static变量的大小然后判断在目标机器上是否合适即可。在逻辑一致性方面,插入断言来验证多个变量之间的逻辑上的互相牵制的关系正常、内存中的值与数据库等外存中的值一致,由于断言可以让你有每天没运行上千上万次(甚至更多倍)的感觉,增强了信心。如果使用单独的测试程序来模拟用户的各种输入操作情况,则会更早发现问题。对于这类问题,其实也没有太多的可注意的(因为并不涉及复杂的架构),自动化地经常性地检测你的内存空间、数据一致,是根本。
      

  13.   

    谢谢!
    谢谢SP1234,cuike519,wuyq11谢谢三位星星!@SP1234,喜欢你回答问题的风格!技术狂人!佩服!