服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 浅析C#静态类,静态构造函数,静态变量

浅析C#静态类,静态构造函数,静态变量

2021-11-24 13:46jerrylsxu C#

这篇文章主要介绍了浅析C#静态类,静态构造函数,静态变量 的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下

静态变量

静态变量位于栈上,它是一个全局变量,在编译期就已经生成。

?
1
2
3
4
5
6
7
8
9
public class Cow
{
public static int count;
private int id;
public Cow()
{
id = ++count;
}
}

客户端创建2个Cow的实例,并打印静态变量count。

?
1
2
3
4
5
6
7
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类中添加一个静态构造函数。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Cow
{
public static int count;
private int id;
public Cow()
{
id = ++count;
}
static Cow()
{
count = new Random().Next(100);
}
}

在构造函数和静态构造函数中,都对Cow的静态字段赋值。现在我们想了解静态构造函数在什么时候触发。是在用构造函数创建实例的时候触发吗?会不会在设置Cow的字段或属性值的时候触发?在客户端,通过打印静态字段count的值来了解静态构造函数什么时候被触发。

?
1
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类修改为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Cow
{
public static int count;
private int id;
public static int whatever;
public Cow()
{
id = ++count;
}
static Cow()
{
count = new Random().Next(100);
whatever = count + 10;
Console.WriteLine("静态构造函数被触发后count为:" + Cow.count);
Console.WriteLine("静态构造函数被触发后whatever为:" + Cow.whatever);
}
}

客户端修改为:

?
1
2
3
4
5
6
7
8
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实例,静态构造函数不会被再次触发

○ 静态构造函数只执行一次

到这里,关于静态构造函数被触发的时机,我们可以这样下结论:无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数是在所有这些动作之前被触发的。

静态类

首先创建一个类,包括静态成员和非静态成员。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Logger
{ private static int logNumber = 0;
static public void InitializeLogging()
{
Console.WriteLine("日志初始化");
}
static public void CloseLog()
{
Console.WriteLine("日志关闭");
}
static public void LogMsg(string msg)
{
Console.WriteLine("日志编号为:" + logNumber + ":" + msg);
}
public void DoSth()
{
Console.WriteLine("我不是静态方法~~");
}
}

在客户端,既可以通过"类名.静态方法名称"调用方法,也可以通过类的实例调用方法。

?
1
2
3
4
5
6
7
8
static void Main(string[] args)
{
Logger.InitializeLogging();
Logger.LogMsg("日志被记录下了~~");
Logger.CloseLog();
Logger logger = new Logger();
logger.DoSth();
}

如果把一个类设置成静态类,意味着:这个类的所有一切存在于栈上,因此该类中不能有实例方法,也不能创建该类实例。

修改Logger类,把实例方法去掉。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static class Logger
{
private static int logNumber = 0;
static public void InitializeLogging()
{
Console.WriteLine("日志初始化");
}
static public void CloseLog()
{
Console.WriteLine("日志关闭");
}
static public void LogMsg(string msg)
{
Console.WriteLine("日志编号为:" + logNumber + ":" + msg);
}
}

在客户端,更不能创建Logger的实例,只能通过"类名.静态方法名"调用方法。

?
1
2
3
4
5
6
static void Main(string[] args)
{
Logger.InitializeLogging();
Logger.LogMsg("日志被记录下了~~");
Logger.CloseLog();
}

总结:

○ 静态变量属于全局,位于栈上

○ 静态构造函数只被触发一次,无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数的触发时机都在这些动作之前

○ 静态类中不能有实例成员

以上内容是小编给大家介绍的C#静态类,静态构造函数,静态变量的全部叙述,希望对大家有所帮助!

延伸 · 阅读

精彩推荐
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15