深入理解C# 静态类与非静态类、静态成员的区别 [转载]

静态类

静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量。在声明一个类时使用static关键字,具有两个方面的意义:首先,它防止程序员写代码来实例化该静态类;其次,它防止在类的内部声明任何实例字段或方法。

静态类是自C# 2.0才引入的,C# 1.0不支持静态类声明。程序员必须声明一个私有构造器。私有构造器禁止开发者在类的范围之外实例化类的实例。使用私有构造器的效果与使用静态类的效果非常相似。

两者的区别:
私有构造器方式仍然可以从类的内部对类进行实例化,而静态类禁止从任何地方实例化类,其中包括从类自身内部。静态类和使用私有构造器的另一个区别在于,在 使用私有构造器的类中,是允许有实例成员的,而C# 2.0和更高版本的编译器不允许静态类有任何实例成员。使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员,编译器将保证不会创建此 类的实例。静态类的另一个特征在于,C#编译器会自动把它标记为sealed。这个关键字将类指定为不可扩展;换言之,不能从它派生出其他类。

静态类的主要特性:
1:仅包含静态成员。
2:无法实例化。
3:是密封的。
4:不能包含实例构造函数。

静态成员
1:非静态类可以包含静态的方法、字段、属性或事件;
2:无论对一个类创建多少个实例,它的静态成员都只有一个副本;
3:静态方法和属性不能访问其包含类型中的非静态字段和事件,并且不能访问任何对象的实例变量;
4:静态方法只能被重载,而不能被重写,因为静态方法不属于类的实例成员;
5:虽然字段不能声明为 static const,但 const 字段的行为在本质上是静态的。这样的字段属于类,不属于类的实例。因此,可以同对待静态字段一样使用 ClassName.MemberName 表示法来访问 const 字段;6:C# 不支持静态局部变量(在方法内部定义静态变量)。

静态构造函数
1:静态类可以有静态构造函数,静态构造函数不可继承;
2:静态构造函数可以用于静态类,也可用于非静态类;
3:静态构造函数无访问修饰符、无参数,只有一个 static 标志;
4:静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数被自动执行,并且只执行一次。

注意:
1:静态类在内存中是一直有位置的;
2:非静态类在实例化后是在内存中是独立的,它的变量不会重复,在使用后会及时销毁,所以不会出现未知的错误。在C#中静态成员是比较敏感的东西,在不是十分确认的情况下不要使用;
3:建议更多地使用一般类(非静态类)。

使用选择:
当定义的类不需要进行实例化时,我们使用静态类;如果需要实例化对象,需要继承等特性时,应该使用非静态类,并且将统一使用的变量和方法设为静态的,那么所有实例对象都能访问。

C# 静态成员和方法的学习小结

数据成员:
数据成员可以分静态变量、实例变量两种.
静态成员:静态成员变量是和类相关联的,可以作为类中"共"有的变量(是一个共性的表现),他不依赖特定对象的存在,访问的时候通过类名加点操作符加变量名来访问.

实例成员:实例成员变量是和对象相关联的,访问实例成员变量依赖于实例的存在.

函数成员:
方法可以主要分为静态方法,实例方法

静态方法:静态方法是不属于特定对象的方法,静态方法可以访问静态成员变量,静态方法不可以直接访问实例变量,可以在实例函数调用的情况下,实例变 量做为参数传给静态方法。静态方法也不能直接调用实例方法,可以间接调用,首先要创建一个类的实例,然后通过这一特定对象来调用静态方法。

实例方法:一个实例方法的执行与特定对象关联,他的执行需要一个对象存在。实例方法可以直接访问静态变量和实例变量,实例方法可以直接访问实例方 法、和静态方法,静态方法的访问方式为类名加点操作符加变量名。当多个实例对象存在时,内存中并不是存在美个特定的实例方法的拷贝,而是,相同类的所有对 象都共享每个实例方法的一个拷贝(实例方法只占用“一套”空间)。
 
如果将类中的某个成员声明为static,则称该成员为静态成员。一般来说,静态成员是属于类所有的,而非静态成员则属于类的实例的。每创建一个类的实 例,都在内存中为非静态成员开辟一片区域。而类的静态成员为类所有,为这个类的所有实例共享。无论这个类创建了多少副本,一个静态成员在内存中只占有一块 区域。

C#类中静态成员变量的生命周期问题,就是什么时候创建,什么时候销毁已声明元素的“生存期”是元素可供使用的时间周期。变量是唯一具有生存期的元 素;为此,编译器将过程参数和函数返回值视为变量的特殊情况。变量的生存期表示它可以保留值的时间周期。在生存期内变量的值可以更改,但变量总是保留某些 值。

不同的生存期

在模块级声明的变量通常在应用程序的整个运行期间都存在。在类或结构中声明的非共享变量作为声明它的类或结构的每个实例的单独副本存在;每个这样的变量都具有与它的实例相同的生存期。但是,Shared 变量仅有一个生存期,即应用程序运行所持续的全部时间。

用 Dim 声明的局部变量仅当声明它们的过程正在执行时存在。这同样适用于过程的参数和任何函数返回值。但是,如果该过程调用其他过程,则局部变量在被调用过程运行期间保留它们的值。

生存期的开始

当执行到声明局部变量的过程时,局部变量的生存期开始。过程一开始执行,每个局部变量即被初始化为其数据类型的默认值。数字变量(包括 Byte 和 Char)被初始化为 0,Date 变量初始化为公元 1 年的 1 月 1 日零时,Boolean 变量初始化为 False,引用类型变量(包括字符串、数组和 Object)初始化为 Nothing。

结构变量的每个成员被视为单独的变量初始化。同样,数组变量的每个元素也单独初始化。

如果变量是用初始值设定项声明的,则在执行变量的声明语句时,将给该变量分配指定的值,如下面的示例所示:

Dim X As Double = 18.973 ' X had previously been initialized to 0.
在过程的内部块中声明的变量在进入该过程时初始化为其默认值。不论该块是否曾执行过,这些初始化都会生效。

生存期的结束

当过程终止时,不再保留该过程的局部变量值,并回收局部元素所使用的内存。下次执行该过程时,将重新创建它的所有局部元素并初始化局部变量。

当类或结构的实例终止时,它的非共享变量丢失它们的值。类或结构的每个新实例都创建它的所有非共享元素并初始化非共享变量。Shared 元素被一直保留到应用程序停止运行时。

生存期的扩展

如果局部变量是用 Static 关键字声明的,则它的生存期比声明它的过程的执行时间长。如果该过程在某模块内,则只要应用程序继续运行,static 变量就一直存在。

如果 static 变量是在类的内部过程中声明的,则该变量的生存期取决于此过程是否共享。如果此过程已用 Shared 关键字声明,则变量的生存期将一直延续到应用程序终止时为止。如果此过程为非共享,则其 static 变量为类的实例成员,并且其生存期与类实例的生存期相同。

在下面的示例中,RunningTotal 函数通过将新值添加到存储在静态变量 ApplesSold 中的以前值的合计来计算流量合计:
 

复制代码 代码示例:
Function RunningTotal(ByVal Num As Integer) As Integer
Static ApplesSold As Integer
ApplesSold = ApplesSold + Num
Return ApplesSold ' ApplesSold keeps its current value.
End Function
 

如果没有使用 Static 就已声明了 ApplesSold,则在函数调用期间将不保留以前累计的值,并且函数只返回上次用来调用它的相同值。

在模块级声明 ApplesSold 可产生相同的生存期。但是,如果这样更改变量的范围,此过程将不再拥有对该变量的独占访问权。由于其他过程可以访问该变量并更改它的值,因此流量合计是不可靠的,并且代码可能会更难维护。

静态成员在第一次被访问之前并且在任何静态构造函数(如调用的话)之前初始化。若要访问静态类成员,应使用类名而不是变量名来指定该成员的位置。

 

原文地址:http://www.cnblogs.com/answercard/p/4797492.html

转载于:https://www.cnblogs.com/taiyonghai/p/7448056.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10配置JAVA和tomacat环境变量

一、配置JAVA_HOME 二、配置CATALINA_HOME (tomacat的环境变量) 三、配置PATH 四、命令行检验配置结果: 1、命令行输入java 2、命令行输入javac 3、命令行输入startup.bat 注:如果以上三个命令无报错表示配置成功 转载于:https://…

1032 挖掘机技术哪家强 (20 分)

1032 挖掘机技术哪家强 (20 分) #include<iostream> using namespace std; int main() {int n,k,h,ch[100101]{0},hh0,hhh1;cin>>n;for (int i0;i<n;i){cin>>k>>h;ch[k]h;if (ch[k]>hh) {hhch[k];hhhk;}}cout<<hhh<<" "&…

E20170830-mk

translation n. 翻译; 译本; 转化; 转变; calculate vt. 计算; 估计; 打算&#xff0c;计划; 旨在;erase vt. 抹去; 清除; 擦掉;转载于:https://www.cnblogs.com/lancgg/p/8281741.html

1033 旧键盘打字 (20 分)

1033 旧键盘打字 (20 分) #include<iostream> using namespace std; int main() {int ch[1011]{0};string str1,str2;getline(cin,str1);getline(cin,str2);int len1str1.length(),len2str2.length();for (int i0;i<len1;i) {if (str1[i]>A&&str1[i]<Z…

3485. 最大异或和

最大异或和 #include <iostream> #include <algorithm> using namespace std; const int maxn 100010, M 31 * maxn; int ch[maxn]; int n; int son[M][2], idx 0; int cnt[M];//M一定要这么大 void insert(int x, int v) {int p 0;for (int i 30; ~i; i--){…

B. Sifid and Strange Subsequences

B. Sifid and Strange Subsequences A sequence (b1,b2,…,bk) is called strange, if the absolute difference between any pair of its elements is greater than or equal to the maximum element in the sequence. Formally speaking, it’s strange if for every pair (…

剑指offer 重建二叉树

重建二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}&#xff0c;则重建二叉树并返回思路&#xff1a;…

y总nb

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情况下&#xff0c;C代码中的操作次数控制在 107∼108107∼108 为最佳。 下面给出在不同数据范围下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; n≤30n≤30, 指数级别, dfs剪枝&#xff0c;状态压缩dp n≤100n…

设计模式 策略模式2 c++11

根据需求的不同 选择不同的策略算法 之前是保存的各种策略类的指针 这里直接使用 function bind 选择对应的算法 代码 // 005.cpp: 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <functional> #include <iostream>using namespace std…

2. 01背包问题

01背包问题 先上版子。 #include<iostream> #include<algorithm> using namespace std; const int maxn 1010; int f[maxn][maxn]; int v[maxn],w[maxn]; int main() {int n,V;cin>>n>>V;for (int i1;i<n;i){cin>>v[i]>>w[i];}for (i…

C++ Websites

C Websites C 推荐网站 1、cprogramming.com 2、cppreference.com 3、cplusplus.com 4、Boost C Library 转载于:https://www.cnblogs.com/xuanyuanchen/p/7457951.html

3. 完全背包问题

完全背包问题 #include <iostream> #include <algorithm> using namespace std; const int maxn 1010; int f[maxn]; int v[maxn], w[maxn]; int main() {int n, V;cin >> n >> V;for (int i 1; i < n; i){cin >> v[i] >> w[i];}for…

python学习(八)定制类和枚举

python定制类主要是实现特定功能&#xff0c;通过在类中定义特定的函数完成特定的功能。 class Student(object):def __init__(self, name):self.name namestudent Student("lilei") print(student) 实现定制类 class Student(object):def __init__(self, name):sel…

4. 多重背包问题 I

多重背包问题 I #include<iostream> #include<algorithm> using namespace std; const int maxn 10010; int f[1001]; int main() {int n,V;cin>>n>>V;for (int i0;i<n;i){int v,w,s;cin>>v>>w>>s;for (int jV;~j;j--){for (in…

题目:16版.雇员的工作职责(一)

题目&#xff1a;16版.雇员的工作职责(一) 1、实验要求 本实验要求&#xff1a;以雇员的日常工作为背景&#xff0c;体验“继承”与“属性复用技术”的运用场景。1-1. 业务说明&#xff1a;1-1.1. 本实验以公司雇员的日常工作模式为业务背景。1-1.2. 公司每个雇员每天都需要进…

架构实战:(一)Redis采用主从架构的原因

架构实战 &#xff08;一&#xff09;Redis采用主从架构的原因 &#xff08;二&#xff09; 如果系统的QPS超过10W&#xff0c;甚至是百万以上的访问&#xff0c;则光是Redis是不够的&#xff0c;但是Redis是整个大型缓存架构中&#xff0c;支撑高并发的架构非常重要的环节。 首…

5. 多重背包问题 II

多重背包问题 II 二进制优化&#xff1a; #include<iostream> #include<vector> #include<algorithm> #include<cstring> using namespace std; int f[10001]; struct node {int v;int w; }; int main() {vector<node>cun;int n,V;cin>>n…

使用memcache作为中间缓存区的步骤

① 直接让PHP程序memcache取数据 ② 如果memcache里面没有数据&#xff0c;则让其连接数据库&#xff0c;去数据库里面取数据 ③ 将取出的数据展示给用户的同时&#xff0c;再将数据缓存到memcache里面&#xff0c;并且可以指定一个缓存的时间&#xff0c;单位为秒。 ④ 如果之…

844. 走迷宫

走迷宫 友情提示&#xff1a;尽量不用fill&#xff0c;用memset 一个fill浪费我两个小时找错。。。。。 #include <iostream> #include <queue> #include <algorithm> #include <cstring> using namespace std; int ch[111][111]; int op[111][111];…

计算机 - 网络原理

计算机 - 网络原理转载于:https://www.cnblogs.com/KevinXia/p/7477693.html