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();
}
}
}在不被实例化的情况下,能被使用的只能是静态或常量。
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();
}
}
}