在C#中调用静态方法会发生什么?

dev*_*747 9 c# static

创建类的实例时,该实例中的所有变量都特定于该实例,并在实例超出范围时被杀死.但它如何在静态方法中工作?假设有两个人在同一时间调用System.Math.Abs​​().运行时如何区分两个调用者?这是线程进来的地方吗?是否为每个调用者自动创建了单独的线程?

Eri*_*ert 12

创建类的实例时,当实例超出范围时,将杀死特定于该实例的所有变量.

变量 - 通常称为"字段" 在实例的生命周期后被释放.范围是程序文本的区域,编译器通过其名称识别某些内容; liftime是存储位置有效的时间部分.范围和寿命经常混淆.

但它如何在静态方法中工作?

静态场具有无限的生命周期; 存储位置是在访问字段之前的某个时间创建的,并且在应用程序域被拆除之前不会被销毁.

假设有两个人在同一时间调用System.Math.Abs​​().

好.您如何提出这种情况?

运行时如何区分两个调用者?这是线程进来的地方吗?

静态方法被嵌入到一堆机器指令中,这些指令是内存中的数字.每个执行线程都有一个与之关联的编号,称为指令当前指令的指令指针.两个不同的线程都可以同时具有同一静态方法内的指令指针.

是否为每个调用者自动创建了单独的线程?

这个问题没有任何意义.如果他们不在单独的线程上,你是如何同时获得两个呼叫者


Mar*_*ell 10

在方法变量生命周期方面,静态和非静态方法之间没有真正的区别.在这两种情况下,作为一个实现细节,本地人通常(不总是:有例外)在堆栈上分配.堆栈是每线程的,因此本地方法变量不会在线程之间交叉.

唯一的区别在这里实例和静态之间是实例方法有一个隐含的零参数,又名"这个",由主叫用户(加上一些虚拟调度和空检查的乐趣)推动.

为简单起见,我正在浏览迭代器块,捕获的变量等.


Jam*_*are 6

即使没有该类的实例,也存在类的所有静态成员.它们在首次使用之前的某个时间进行初始化,并在程序完成时进行清理.

如果您同时调用静态方法,则它们将使用该类的任何静态成员的相同副本(如果他们使用它们).因此,如果静态方法对静态成员(或参数)进行操作,则应以线程安全的方式进行操作.如果静态方法仅在本地操作,则方法本身通常是线程安全的.

至于运行时如何区分两个调用者,这是线程的本质.每个线程都有自己的调用堆栈,它有自己的任何局部变量,参数,返回地址等的副本.因此,两个调用不会混淆,每个调用都会正确返回其调用者.唯一的问题是,如果静态方法对非线程安全的静态成员(或非线程安全的参数)进行操作.