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(); // 附加一句,在实例上调用静态成员也是错误的!

  }

  }

  }

时间: 2024-10-04 13:19:06

c#中main函数为什么要static的相关文章

在C++工程中main函数之前跑代码的廉价方法(使用全局变量和全局函数)

[cpp] view plain copy // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <crtdbg.h> /// 在C++工程中main函数之前跑代码的廉价方法 /// 利用全局变量可以赋可变初值的事实 /// mainCRTStartup() => _cin

python 中main函数总结

Python使用缩进对齐组织代码的执行,所有没有缩进的代码(非函数定义和类定义),都会在载入时自动执行,这些代码,可以认为是Python的main函数. 每个文件(模块)都可以任意写一些没有缩进的代码,并且在载入时自动执行,为了区分主执行文件还是被调用的文件,Python引入了一个变量__name__,当文件是被调用时,__name__的值为模块名,当文件被执行时,__name__为'__main__'.这个特性,为测试驱动开发提供了极好的支持,我们可以在每个模块中写上测试代码,这些测试代码仅当

对于Java中main函数为虚函数以及多态的一点理解

Question: 1.在Java中,由于main函数的定义为: public static void main(String[] args):那么要想在main函数中调用其余的函数的话,就必须将定义为static.另外,调用其他类编写的成员函数时,却不需要该成员函数为静态的,这是为什么? 分析: 静态方法是属于某一个类所有,而非静态方法是属于某类的对象所有.也就是说,要想调用非静态方法,必须先调用new来得到一个类的对象,系统为其分配内存,然后才能通过该对象访问相应的非静态成员函数.而静态方法

大数据学习之Scala中main函数的分析以及基本规则(2)

一.main函数的分析 首先来看我们在上一节最后看到的这个程序,我们先来简单的分析一下.有助于后面的学习 object HelloScala { def main(args: Array[String]): Unit = { println("I Love You Scala"); } } 如图所看到的,在Scala中能够使用object和class分别定义一个类.两者还是存在一些区别.以后我会在专门的博客中给予介绍. 在Scala中定义一个函数使用:def 来修饰 完整定义一个函数为

Linux中Main函数的执行过程

1. 问题:Linux如何执行main函数. 本文使用一个简单的C程序(simple.c)作为例子讲解.代码如下, int main() { return(0); } 2.  编译 -#gcc -o simple simple.c 3. 查看可执行文件的基本信息 -#objdump -f simple simple: file format elf32-i386 architecture: i386, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED sta

C 中 main 函数的参数

      看到不同的人写出的 C 或者 C++ 程序时,可能会出现不一样的 main 函数的定义,下面的几种定义方式都是对的: int main(void) int main(int argc) int main(int argc, /*const*/ char** argv) int main(int argc, /*const*/ char** argv, /*const*/ char** enviorn)       这几种方式中,第三种方式是最常用的.那么,这些参数代表着什么呢?下面,

Java中main函数深入理解

最开始学习Java,接触到的应该就是main函数: Public static void main(String args[]){} 但是main函数为什么要这样写,又隐藏了哪些被忽视的知识,今天深入学习一下. 关键字分析     最直观的就是逐个关键字分析, 1.public 2.static 3.参数args[] 入口函数小结

C99 中 main 函数的写法

今天在论坛看见有人讨论 C 语言中 Main 函数的写法,看到结论才知道 Main 函数的正确写法. 被老谭酸菜坑了这么多年,还是记录下吧,或许以后某天不搞 .net,回去折腾 C 语言了. 写法1: 1 int main(void) 2 { 3 // TODO 4 return 0; 5 } 写法2: 1 int main(int argc, char *argv[]) 2 { 3 // TODO 4 return 0; 5 } 两种写法都是符合 C99 标准的,当然第二种是适用范围更广泛.

Java中main函数参数String args[] 和 String[] args 区别

其实没什么区别的:当初我也是这样的疑问,呵呵:非要说区别就看下面:执行效果上没有不同, 但在语法意义上略有不同. 比如, String与String[], 前者叫字符串类型而后者叫字符串数组类型. String args[]单从类型上来讲属于字符串类型, 而从变量本身来讲是一个数组类型, 因此组合起来说明此变量为一个字符串类型的数组, 也就是说数组中的所有元素都为String类型. String[] args单从类型上来讲属于字符串数组类型, 而从变量本身来讲就是一个单纯的引用变量, 因此这种方