博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类的静态构造函数的其他几个注意点
阅读量:6568 次
发布时间:2019-06-24

本文共 3485 字,大约阅读时间需要 11 分钟。

1. 禁止在一个类的静态构造函数中访问另一个类中的静态成员。

   猜下下面这段程序的输出结果:

using
 System;
using
 System.Threading;
namespace
 TypeConstructorLock
...
{
    
class Class1
    
...{
        [STAThread]
        
public static void Main(string[] args)
        
...{
            Thread threadA 
= new Thread(new ThreadStart(TouchStatic1));
            threadA.Name 
= "Thread A";
      
            Thread threadB 
= new Thread(new ThreadStart(TouchStatic2));
            threadB.Name 
= "Thread B";
 
            threadA.Start();
            threadB.Start();
            threadA.Join();
            threadB.Join();
        }
 
        
static void TouchStatic1() ...string s = Static1.Message; }
        
static void TouchStatic2() ...string s = Static2.Message; }
    }
    
class Static1
    
...{
        
static Static1()
        
...{
            Console.WriteLine(
"Begin Static1 .cctor on thread {0}"
                Thread.CurrentThread.Name);
            Thread.Sleep(
5000);
            Console.WriteLine(
"//Static1 has a message from Static2: {0}"
                Static2.Message);      
            message 
= "Hello From Static1";
            Console.WriteLine(
"Exit Static1 .cctor on thread {0}"
                Thread.CurrentThread.Name);
        }
 
        
static public string Message ...get ...return message; } }
        
static string message = "blank";
    }
 
    
class Static2
    
...{
        
static Static2()
        
...{
            Console.WriteLine(
"Begin Static2 .cctor on thread {0}"
                Thread.CurrentThread.Name);
            Thread.Sleep(
5000);
            Console.WriteLine(
"//Static2 has a message from Static1: {0}"
                Static1.Message);         
            message 
= "Hello From Static2";
            Console.WriteLine(
"Exit Static2 .cctor on thread {0}"
                Thread.CurrentThread.Name);
        }
 
        
static public string Message ...get ...return message; } }
        
static string message = "blank";    
    }
}

   执行结果:

E:CSC
>
staticlock.exe
Begin Static1 .cctor on thread Thread A
Begin Static2 .cctor on thread Thread B
//
Static2 has a message from Static1: blank
Exit Static2 .cctor on thread Thread B
//
Static1 has a message from Static2: Hello From Static2
Exit Static1 .cctor on thread Thread A

    留意上面的“//static2 has a message from static1:black”,里面取得的字符串值是“blank”,而不是“Hello From Static1”,我们不能确定两个静态构造函数中的两条message赋值语句谁已经执行或没有执行! 这里要记住一条规则:禁止在一个类的静态构造函数中访问另一个类中的静态成员(Avoid touching the static members of another type from within a type constructor)。虽然我们很少情况下会写出上面这种代码,但一旦写出来了,这种错误将很难调试,我们要牢记这样准则。

 

2. 如果静态构造函数中有异常(用E描述)抛出,则CLR会对E进行包装,重新抛出一个System.TypeInitializationException异常,而把E作为该异常的InnerException。在进行程序设计时,我们一定要保证在类的静态构造函数不能有异常抛出!

3. C#中不支持子类继承父类的静态成员,但却可以通过子类类名来访问父类的静态成员!
   反射静态成员的示例:

using
 System;
using
 System.Reflection;
namespace
 Reflection
...
{
    
class Class1
    
...{
        [STAThread]
        
static void Main(string[] args)
        
...{           
            Type type;              
            
object result;
            PropertyInfo[] properties;
            
            
object instance = null;
            
object[] index = null;
            
            type 
= typeof(Static1);
            
            properties 
= type.GetProperties(BindingFlags.Static | BindingFlags.Public);            
            result 
= properties[0].GetValue(instance, index);//注意:访问内的静态成员,这里传入的是null
            Console.WriteLine(result.ToString());
            
            type 
= typeof(Static2);
            
            properties 
= type.GetProperties(BindingFlags.Static | BindingFlags.Public |
                 BindingFlags.FlattenHierarchy);
//如果不运用FlattenHierarchy,则返回空数组。
        /**//*FlattenHierarchy:指定应返回层次结构上的公共静态成员和受保护的静态成员。
         * 不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
         *
         * FlattenHierarchy告诉CLR将基类Static1的静态属性也算在内!
         * C#中不支持子类继承父类的静态成员,但却可以通过子类类名来访问父类的静态成员!
         * e.g.:我们可以通过访问Static2.Message来访问Static1.Message
         *  
*/
            result 
= properties[0].GetValue(instance, index);
            Console.WriteLine(result.ToString());
        Console.WriteLine(Static2.Message);
        }
    }
            
    
class Static1
    
...{
        
static public string Message ...get ...return message; } }
        
static string message = "Hello World 1";
    }
            
    
class Static2 : Static1...{}
}

   执行结果:

E:CSC
>
refstatic.exe
Hello World 
1
Hello World 
1
 

 

 

参考:

转载于:https://www.cnblogs.com/happyhippy/archive/2007/04/05/710935.html

你可能感兴趣的文章
一个HexToInt的C/C++函数
查看>>
使用SVN进行项目版本管理
查看>>
【vijos】1729 Knights(匈牙利)
查看>>
浅谈ASP.net处理XML数据
查看>>
抽象基类
查看>>
Linux 下Tomcat的启动、关闭、杀死进程
查看>>
第一章. ActionScript 语言基础
查看>>
jQuery中position()与offset()区别
查看>>
告别码农,成为真正的程序员
查看>>
java常量设置的方式
查看>>
如何使用AdvancedInstaller在安装包中运行一个.bat文件
查看>>
linux 信号处理 六(全)
查看>>
Linear regulator=low-cost dc/dc converter
查看>>
百度地图与HT for Web结合的GIS网络拓扑应用
查看>>
spark资料汇集
查看>>
HTML的disabled属性及readonly属性
查看>>
Linux Vi 删除全部内容,删除某行到结尾,删除某段内容 的方法
查看>>
EditorWindow中手动控制焦点
查看>>
textarea文本域宽度和高度(width、height)自己主动适应变化处理
查看>>
linux 常用awk命令
查看>>