NET/C# 中 Main() 方法与它所在的类,如 (Program class) 的关系

 namespace TestProjectG
{
    class Program 
   {       
    int i = 0;      
    static void Main(string[] args)       
    {           
      Console.WriteLine(i);       
    }   
  }
}
上面这段代码是有问题的,就是因为,如果下意识的把Main方法当作类Program(当然其它名字也一样,不过默认生成的是这个)的一个成员方法的话,那么就会想当然的认为类的方法在类内部使用类的成员变量,即使这个是私有的成员变量,也不会有问题吧?事实上不是,Main方法其实不能考虑为它所在类的成员方法,如果在Main中要使用任何成员变量,要么是在Main方法自己内部声明的局部变量,要么是来自于其它类的变量,必须使用合适的引用方法。
就是说Main方法与它所在的类没有任何关系,它只是被安排放在某个类中,你完全把它放在任意的其它类中,不影响任何使用效果。

---有人帮我评论了我才意识到,Main() 方法确实是一个静态方法 ,当然就不能使用类的非静态成员变量了,非常感谢评论的二位~

另外我前面的想法是完全错误的,一旦一个Main()方法被加入到某个类中,它就确实成为这个类的一部分了,证据如下:

   
   
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 1 namespace TestProjectG 2 { 3 class Program 4 { 5 private static int i = 0 ; 6 public static void Main( string [] args) 7 { 8 Console.WriteLine(i); 9 } 10 } 11 }

Main()方法可以访问该类中的静态的私有字段,在IL中是这样子的:

 .method public hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldsfld     int32 TestProjectG.Program::i
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Program::Main

 因此,Main()方法跟它所在的类是有关系的。事实上,在实际的软件系统中,涉及到Main()方法及其所在的类的问题占整个系统问题的比重极低极低,它只做为一个入口存在,真正费思量的地方,还是在其它核心类上。
****************************************************************************************
我本人的补充说明:Main()方法做为程序的入口函数,必须是static的,因为它是在没有被实例化的情况下运行的,而做为静态方法,不能访问其包含类型中的非静态字段和事件。如果Main调用类Program中的方法,那么这个方法也应该是static的。下面为我调试用的一段代码:
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test
{
    class Program
    {
        static AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
        static void Thread1Foo()
        {
            _autoResetEvent.WaitOne();
            Console.WriteLine("t1 end");
            Console.WriteLine("Press any key to exit. ");
            Console.ReadKey();
        }
        static void Main(string[] args)
        {         
            Thread t1 = new Thread(Thread1Foo);
            t1.Start();
            Thread.Sleep(3000);
            _autoResetEvent.Set();     
        }
    }
}在不被实例化的情况下,能被使用的只能是静态或常量。

那么如果做一些代码的测试的时候怎么办呢,其实可以在Main()命名空间中,除了class Program,自己可以创建多一个类或多个,然在Main()中实例化这个类来测试代码,而Main()只是做为程序的入口。
当然还有一种,就是初始化自己所在的类Program,我觉得这个不错。

using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace test
{
    class Program
    {
        public AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
        public void Thread1Foo()
        {
            _autoResetEvent.WaitOne(); //阻塞当前线程直到,运行了_autoResetEvent.Set(),_autoResetEvent 返回终止状态。
            Console.WriteLine("t1 end");
            Console.WriteLine("Press any key to exit. ");
            Console.ReadKey();
        }  
      //t1线程执行完后,_autoResetEvent自动返回为非终止状态。
        public void Runtest()
        {
            Thread t1 = new Thread(Thread1Foo);
            t1.Start();
            Thread.Sleep(3000);//Thread.Sleep(Int32)是指当前进程挂起3000毫秒,与线程t1是一点关系也没有的。
            _autoResetEvent.Set();由于前面挂起了3秒后,才将事件状态设置为终止状态,允许一个或多个等待线程继续。
        }
        static void Main(string[] args)
        {
            Program p1 = new Program();
            p1.Runtest();            
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值