C#中Main函数为什么要static
假设没有static关键字,那意味着需要用生成一个实例后才可以调用这个Main方法,而Main方法是程序入口点,你没有进入Main方法,自然无法生成一个实例,既然没有实例,那就无法调用Main函数,岂不矛盾?所以Main函数被设置为static.
Main()函数在C#里非常特殊,它是编译器规定的所有可执行程序的入口点。由于其特殊性,对Main()函数我们有以下几条准则:
Main()函数必须封装在类或结构里来提供可执行程序的入口点。C#采用了完全的面向对象的编程方式,C#中不可以有像C++那样的全局函数。
Main()函数必须为静态函数(static)。这允许C#不必创建实例对象即可运行程序。
Main()函数保护级别没有特殊要求, public,protected,private等都可,但一般我们都指定其为public。
Main()函数名的第一个字母要大写,否则将不具有入口点的语义。C#是大小写敏感的语言。
Main()函数的参数只有两种参数形式:无参数和string 数组表示的命令行参数,即static
void Main()或static void Main(string[]args) ,后者接受命令行参数。一个C#程序中只能有一个Main()函数入口点。其他形式的参数不具有入口点语义,C#不推荐通过其他参数形式重载Main()函数,这会引起编译警告。
Main()函数返回值只能为void(无类型)或int(整数类型)。其他形式的返回值不具有入口点语义。
在C#中,static变量表示该变量属于类,而不是类的实例。"static"修饰符声明一个静态元素,而该元素属于类型本身而不是指定的对象,可以说是该类的所有实例共享一个static变量。
看看什么是 static class 吧,刚开始我就为不能声明一个 abstract sealed class
而苦恼不已,abstract 和 sealed一起用?定义abstract的目的就是抽象基类,seal表示不能继承的实体类,完全是两回事,怎么可能一起用呢?abstract表明必须要被继承,sealed表明不可以被继承,这两个是矛盾的,怎么可以一起用呢。
通过查看 IL 代码,我们会发现 static class 实际上就是 abstract sealed class,
只不过编译器在编译时顺便对 static class 的成员修饰符进行检查而已。让我们再来猜测一下 MS 开发人员的想法:他们的目的是想获得 abstract sealed class 的效果,但却为语义上的矛盾而苦恼不已,大家想获得一个优美的解决方式,于是就为 C 2.0 新增了一个 static 关键字,完美的解决了这个问题。
也许有人会问:为什么不是 static class = abstract class + static member limit
而要加上 sealed 的限制呢?理由是继承一个只有 static 成员的类和重新写一个类完
全没有区别。为什么这么说呢?因为 static 必然是not virtual,继承它又能有什么
用呢?
static class 还有一个限制,那就是只能从 System.Object 继承,为什么会有这个限
制,理由和上面差不多。
每每提到 static 关键字,我就想起了 static constructor,感谢 MS 的开发人员提
供了这么好的一个特性。但是 C 提供了 static constructor 却没有提供static destructor,不过在 Applied Microsoft .NET Framework Programming 一书中
Jeffery Richter 给我们提供了一个办法就是通过 System.AppDomain.DomainUnload
事件去达到同样的效果。使用 static constructor 要注意的就是这里抛出任何异常都会导致该类型在重新加载AppDoamin 之前不再可用,所以要加倍小心,另外 static contructor 中很容易有两个类型死锁的情况发生,在编写代码的时候一定要想清楚。
const与 readonly的区别 const==static readonly
const 的概念就是一个包含不能修改的值的变量。
常数表达式是在编译时可被完全计算的表达式。因此不能从一个变量中提取的值来初始化常量。如果 const int a = b+1;b是一个变量,显然不能再编译时就计算出结果,所以常量是不可以用变量来初始化的。
readonly 允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值。
因为 readonly 是在计算时执行的,当然它可以用某些变量初始化。
readonly 是实例成员,所以不同的实例可以有不同的常量值,这使readonly更灵活。
readonly 关键字与 const 关键字不同。
1. const 字段只能在该字段的声明中初始化。
readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。
2. const 字段是编译时常数,而 readonly 字段可用于运行时常数。
3. const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明。
4.const 对于引用类型的常数,可能的值只能是 string 和 null。
readonly可以是任何类型
----------------------------
非静态成员又称实例成员,必须作用于实例。在程序刚开始运行的时候,未建立任何实例,因此无法调用实例成员,包括非静态的Main方法。为了能够在程序的开始执行Main方法,必须将其声明为静态。
顺便说明,在Main方法中调用的成员也必须是静态的,除非建立过相应的实例。
例如:
namespace lover_P.Test {
public class Test {
public void InstanceMethod() {} // 实例成员(非静态)
public static void StaticMethod {} // 类型成员(静态)
public static void Main() {
InstanceMethod(); // 错误!调用了实例成员,而此时并没有建立实例
StaticMethod(); // 正确!可以调用静态成员
Test SomeTest = new Test(); // 建立本类型的一个实例
SomeTest.InstanceMethod(); // 再在这个实例上调用实例成员就对了
SomeTest.StaticMethod(); // 附加一句,在实例上调用静态成员也是错误的!
}
}
}
原文链接:http://net5x.blog.51cto.com/7900145/1568257%20
C#中Main函数为什么要static的更多相关文章
- eclipse 中main()函数中的String[] args如何使用?通过String[] args验证账号密码的登录类?静态的主方法怎样才能调用非static的方法——通过生成对象?在类中制作一个方法——能够修改对象的属性值?
		eclipse 中main()函数中的String[] args如何使用? 右击你的项目,选择run as中选择 run configuration,选择arguments总的program argu ... 
- .NET中Main函数使用小技巧
		摘要:任何语言开发出来的程序,都会有一个程序入口函数,可能每个语言所使用的程序入口函数名称不一样,但是它们的作用都是一样的,都是被操作系统去调用.那么本文主要总结.NET中的程序入口函数Main使用的 ... 
- 在C++工程中main函数之前跑代码的廉价方法(使用全局变量和全局函数)
		// test.cpp : Defines the entry point for the console application. // #include "stdafx.h" ... 
- 关于C/C++中main函数参数的学习
		因为面对对象作业(2018.5.21)的要求,去学习了C/C++中main函数参数的意义,以及一些简单的使用(从命令行指令的接受),不给予赘述.(仅为个人拙见,还望看官指正) 首先,带有参数的main ... 
- java中main函数怎么调用外部非static方法
		使用外部方法时(不管是static还是非static),都要先new一个对象,才能使用该对象的方法. 举例如下: 测试函数(这是错误的): public class Test { public sta ... 
- java中main函数解析(转载)
		从写java至今,写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己,为什么要这么写,因为在c语言中就没有这样子的要 ... 
- java中main函数解析
		从写java至今,写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己,为什么要这么写,因为在c语言中就没有这样子的要 ... 
- Linux中Main函数的执行过程
		1. 问题:Linux如何执行main函数. 本文使用一个简单的C程序(simple.c)作为例子讲解.代码如下, int main() { return(0); } 2. 编译 -#gcc -o ... 
- c/c++中main函数参数讲解
		参考地址: http://blog.csdn.net/cnctloveyu/article/details/3905720 我们经常用的main函数都是不带参数的.因此main 后的括号都是空括号.实 ... 
随机推荐
- cad.net之ACAD移植到GCAD的自动加载问题
			将acad.pgp,lsp,fas,vlx,名称增加一份gcad.pgp,lsp,fas,vlx.涉及系统加载用. Lisp的拖拉加载在gcad无法通过lastprompt获取命令历史栏最后一行(含路 ... 
- 跟着刚哥学习Spring框架--JDBC(六)
			Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要提供JDBC模板方式.关系数据库对象化方式.SimpleJdbc方式.事务管理来简 ... 
- 【ElasticSearch】:索引Index、文档Document、字段Field
			因为从ElasticSearch6.X开始,官方准备废弃Type了.对应数据库,对ElasticSearch的理解如下: ElasticSearch 索引Index 文档Document 字段Fiel ... 
- Upgrade Win10
			Internal deployment of Windows 10 Enterprise is currently underway as a phased deployment. Watch you ... 
- redis缓存存在的隐患及其解决方案
			redis缓存1.缓存穿透 1>.什么是缓存穿透? 业务系统需要查训的数据根本不存在,当业务系统查询时, 首先会在缓存中查训,由于缓存中不存在,然后在往数据 库中查,由于该数据在数据库中也不存在 ... 
- 在Ubuntu下编译安装nginx
			一.安装nginx 1.安装前提 a)epoll,linux内核版本为2.6或者以上 b)gcc编译器,g++编译器 c)pcre库,函数库,支持解析正则表达式 d)zlib库:压缩解压功能 e)op ... 
- How To Scan QRCode For UWP (2)
			这篇随笔主要介绍照相预览功能,重要使用的是MediaCapture对象,MediaCapture对象还可以用来处理录音和录制视频,本文只讨论照相功能. 1:查找摄像头 后置摄像头优先,找不到后置摄像头 ... 
- 常见数据结构的Java实现
			单链表的Java实现 首先参考wiki上的单链表说明,单链表每个节点包含数据和指向链表中下一个节点的指针或引用.然后看代码 import java.lang.*; public class Singl ... 
- Android开发艺术探索学习笔记(六)
			第六章 Android的Drawable Drawable的优点:使用简单,比自定义view的成本要低:非图片类型的Drawable占用空间小,有利于减小APK安装包的大小. 6.1Drawable ... 
- Notepad++中代码格式化插件NppAStyle
			本文以图片和说明,手把手教大家怎么让Notepad++中的代码风格看起来更美观. 工具/原料 Windows7 Notepad++ NppAStyle(Notepad++的一个插件) 方法/步骤 直 ... 
