C#静态类,静态构造函数,静态变量
静态变量位于栈上,它是一个全局变量,在编译期就已经生成。
public class Cow
public static int count;
private int id;
{
id = ++count;
}
客户端创建2个Cow的实例,并打印静态变量count。
static void Main(string[] args)
Console.WriteLine(Cow.count);
Cow cow1 = new Cow();
Cow cow2 = new Cow();
Console.WriteLine(Cow.count);
}
结果:
0
2
○ 在创建Cow实例之前,全局就已经有了count这个静态变量
○ 如果在static之前用private修饰,就不可以通过"类名.静态字段名"来访问静态字段,但全局的静态字段始终存在
在堆和栈上的表现,如下图:

静态构造函数
在Cow类中添加一个静态构造函数。
public class Cow
public static int count;
private int id;
{
id = ++count;
static Cow()
count = new Random().Next(100);
}
在构造函数和静态构造函数中,都对Cow的静态字段赋值。现在我们想了解静态构造函数在什么时候触发。是在用构造函数创建实例的时候触发吗?会不会在设置Cow的字段或属性值的时候触发?在客户端,通过打印静态字段count的值来了解静态构造函数什么时候被触发。
static void Main(string[] args)
Cow cow1 = new Cow();
Console.WriteLine("创建第一个Cow实例后count为:"+ Cow.count);
Cow cow2 = new Cow();
Console.WriteLine("创建第二个Cow实例后count为:" + Cow.count);
○ 静态构造函数在创建第一个Cow实例的时候被触发
○ 在创建第二个Cow实例的时候,静态构造函数没有被触发,而是通过构造函数创建实例
○ 静态构造函数只执行一次
由此,我们是否可以这样定论:静态构造函数是在创建第一个实例时候被触发的?
横看成岭侧成峰,来换个角度思考这个问题。在为类的字段赋值时,会不会触发静态构造函数呢?
把Cow类修改为:
public class Cow
public static int count;
private int id;
public static int whatever;
{
id = ++count;
static Cow()
count = new Random().Next(100);
whatever = count + 10;
Console.WriteLine("静态构造函数被触发后count为:" + Cow.count);
Console.WriteLine("静态构造函数被触发后whatever为:" + Cow.whatever);
}
客户端修改为:
static void Main(string[] args)
Cow.count = 100;
Cow cow1 = new Cow();
Console.WriteLine("创建第一个Cow实例后count为:"+ Cow.count);
Cow cow2 = new Cow();
Console.WriteLine("创建第二个Cow实例后count为:" + Cow.count);
○ 在为Cow的字段赋值之前,静态构造函数被触发
○ 接着创建Cow实例,静态构造函数不会被再次触发
○ 静态构造函数只执行一次
到这里,关于静态构造函数被触发的时机,我们可以这样下结论:无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数是在所有这些动作之前被触发的。
静态类
首先创建一个类,包括静态成员和非静态成员。
public class Logger
private static int logNumber = 0;
{
Console.WriteLine("日志初始化");
static public void CloseLog()
Console.WriteLine("日志关闭");
static public void LogMsg(string msg)
Console.WriteLine("日志编号为:" + logNumber + ":" + msg);
public void DoSth()
Console.WriteLine("我不是静态方法~~");
}
在客户端,既可以通过"类名.静态方法名称"调用方法,也可以通过类的实例调用方法。
static void Main(string[] args)
Logger.InitializeLogging();
Logger.LogMsg("日志被记录下了~~");
Logger.CloseLog();
Logger logger = new Logger();
logger.DoSth();
}
如果把一个类设置成静态类,意味着:这个类的所有一切存在于栈上,因此该类中不能有实例方法,也不能创建该类实例。
修改Logger类,把实例方法去掉。
public static class Logger
private static int logNumber = 0;
{
Console.WriteLine("日志初始化");
static public void CloseLog()
Console.WriteLine("日志关闭");
static public void LogMsg(string msg)
Console.WriteLine("日志编号为:" + logNumber + ":" + msg);
}
在客户端,更不能创建Logger的实例,只能通过"类名.静态方法名"调用方法。
static void Main(string[] args)
Logger.InitializeLogging();
Logger.LogMsg("日志被记录下了~~");
Logger.CloseLog();
}
总结:
○ 静态变量属于全局,位于栈上
○ 静态构造函数只被触发一次,无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数的触发时机都在这些动作之前
○ 静态类中不能有实例成员
C#静态类,静态构造函数,静态变量的更多相关文章
- MVC5中Model层开发数据注解 EF Code First Migrations数据库迁移 C# 常用对象的的修饰符 C# 静态构造函数 MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上) MVC 的HTTP请求
MVC5中Model层开发数据注解 ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证( ...
- 关于C#的静态类和静态构造函数
静态构造函数是C#的一个新特性,其实好像很少用到.不过当我们想初始化一些静态变量的时候就需要用到它了.这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次.也就是在创建第一个 ...
- 编写高质量代码改善C#程序的157个建议——建议106:为静态类添加静态构造函数
建议106:为静态类添加静态构造函数 静态类可以拥有构造方法,这就是静态构造方法.静态构造方法与实例构造方法比较有几个自己的特点: 只被执行一次,且在第一次调用类成员之前被运行时执行. 代码无法调用它 ...
- C#静态类、静态构造函数,类与结构体的比较
一.静态类 静态类是不能实例化的,我们直接使用它的属性与方法,静态类最大的特点就是共享. 探究 public static class StaticTestClass{ public stati ...
- c#学习系列之静态类,静态构造函数,静态成员,静态方法(总之各种静态)
<1>静态类: 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量.静态类最大的特点就是共享.在声明一个类时使用static关键字,具有 ...
- 深入了解C#中的静态变量和静态构造函数
深入的剖析C#中静态变量和静态构造函数: 在日常的程序开发过程经常会使用到静态变量,众所周知,静态变量时常驻内存的变量,它的生命周期是从初始化开始一直到Application结束.但是,我们经常会忽略 ...
- C# - 静态类和静态构造函数
一个类只能有一个静态构造函数,该构造函数不能有访问修饰符,不能带任何参数,不能直接调用,只能在: 1 创建包含静态构造函数的类实例时 2 访问包含静态构造函数的静态成员时 会先调用静态构造函数,无论创 ...
- java类中,成员变量赋值第一个进行,其次是静态构造函数,再次是构造函数
如题是结论,如果有人问你Java类的成员初始化顺序和初始化块知识就这样回答他.下面是代码: package com.test; public class TestClass{ // 成员变量赋值第一个 ...
- C# 静态构造函数,静态变量执行顺序(精华版)(规正版)
一.成员初始化整体顺序 1.成员赋值初始化先于构造函数: 2.成员赋值初始先从子类再到基类: 3.构造函数初始化先从基类再到子类: 4.静态成员初始化优先于实例成员初始化: 二.对类型静态成员构造的大 ...
随机推荐
- git-常用命令一览表
一.git bash 操作文件 常用命令表 git常用 文件操作 命令 功能分类 命令 说明 备注 目录切换 cd 文件目录 改变/切换 目录, change directory 如 cd e:\ff ...
- 百度前端学院js课堂作业合集+分析(更新中...)
第一课:简陋的登录框 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- Spring.NET依赖注入框架学习-- 泛型对象的创建和使用
Spring.NET依赖注入框架学习-- 泛型对象的创建和使用 泛型对象的创建方法和普通对象是一样的. 通过构造器创建泛型对象 下面是一个泛型类的代码: namespace GenericsPlay ...
- python tkinter教程-事件绑定
一个Tkinter主要跑在mainloop进程里.Events可能来自多个地方,比如按键,鼠标,或是系统事件. Tkinter提供了丰富的方法来处理这些事件.对于每一个控件Widget,你都可以为其绑 ...
- sencha touch list + carousel scrollable(与其他控件共用滚动条)
有些时候我们需要实现这种效果 上边是一张图片或者一个跑马灯控件,这个布局实现起来比较容易 但是如何让他们共用一个滚动条,来实现以下效果就比较麻烦了. 在官方论坛查找资料得知,可以用以下写法实现: /* ...
- linux 简单搭建git服务器
如果使用git的人数较少,可以使用下面的步骤快速部署一个git服务器环境. 1. 生成 SSH 公钥 每个需要使用git服务器的工程师,自己需要生成一个ssh公钥进入自己的~/.ssh目录,看有没有用 ...
- 使用spring提供的ReflectionUtils简化项目中反射代码的复杂性
在项目中有时候我们会使用到反射的功能,如果使用最原始的方法来开发反射的功能的话肯能会比较复杂,需要处理一大堆异常以及访问权限等问题.spring中提供了ReflectionUtils 这个反射的工具类 ...
- 单例模式全面学习(C++版)
单例模式:用来创建独一无二的,只能够有一个实例的对象. 单例模式的结构是设计模式中最简单的,但是想要完全实现一个线程安全的单例模式还是有很多陷阱的,所以面试的时候属于一个常见的考点~ 单例模式的应用场 ...
- 新浪的动态策略灰度发布系统:ABTestingGateway
原文链接:http://www.open-open.com/lib/view/open1439889185239.html ABTesingGateway 是一个可以动态设置分流策略的灰度发布系统,工 ...
- Ubuntu 16.04系统下解决Vim乱码问题
方法: 打开终端输入:vim /etc/vim/vimrc,进入编辑模式,加入如下配置: set fileencodings=utf-8,gb2312,gbk,gb18030 set termenco ...