我想知道为什么在Main
方法中始终需要对象引用来调用子类的方法。
但是我们可以通过其他方法的方法名称直接调用Main
方法:
using System;
class MainProgram : Parent_Class
{
static void Main(string[] args)
{
Project1_Child p = new Project1_Child();
p.PI_add(); //-> Object reference is required
}
public void non_Main_method()
{
PI_add(); //-> No Object reference is required
}
}
public class Parent_Class
{
public void PI_add()
{
Console.WriteLine("-------------");
}
}
为什么会这样?
答案 0 :(得分:7)
正如其他答案所述,您需要了解静态方法和实例方法之间的区别。这个答案的要点是让你走上正确的术语路径,并考虑对实例方法的调用。你说:
我想知道为什么在Main方法中总是需要一个对象引用来调用子类的方法。
让我们分解。
x = foo.Bar(123)
时,您正在发送消息"至foo
关于您希望foo
执行哪些计算,foo
将结果发回给x
。this.
MainProgram.
然后解释了你的观察结果。
在Main
中,您拨打PI_add
。那是一个实例成员,所以它需要一个接收器作为实例。如果您从中调用实例成员,则C#会认为您已将this.
省略,但您是从静态成员调用的。因此接收器是必需的,忽略接收器是错误的。
在non_main_method
实例方法中,您调用PI_add
。它是一种实例方法,因此假设省略的接收者为this.
这足以让您走上更高效的道路。当您了解委托和扩展方法时,您会发现这里有更多的细微之处,关于接收器究竟是什么以及编译器如何处理它。
答案 1 :(得分:0)
因为main
方法是静态方法,non_Main_method
是实例方法。
静态方法属于该类型,而不属于特定实例,因此为了在其中执行实例方法,必须首先创建该类型的实例。
使用static修饰符声明一个静态成员,该成员属于该类型本身而不是特定对象。
来自Static Classes and Static Class Members (C# Programming Guide):
静态方法和属性无法访问其包含类型中的非静态字段和事件,并且除非在方法参数中显式传递,否则它们无法访问任何对象的实例变量。
虽然最后一部分不准确 - You are allowed to create an instance of the class inside a static method - 但它不必作为参数传递。
答案 2 :(得分:0)
调用类的非静态方法(如示例中的PI_add())实际上只是
的简写符号this.PI_add();
反过来(基本上)只是一个简写符号,用于调用(几乎)等效的静态方法(它实际上并不存在于你的命名空间中)
PI_add_static(this);
但是如果你试图从像Main这样的静态方法调用PI_add(),那么在静态函数中永远不会有这个对象。这是因为静态方法 - 按定义 - 不属于任何对象。因此,您要做的就是致电
PI_add_static(); // argument missing
你错过了传递参数的地方。现在可能很清楚,这不起作用。
顺便说一句:请注意,我说'#34;基本上"将PI_add_static(this)与this.PI_add()进行比较时。实际上,它们在现实中的不同之处在于所有面向对象的核心:非静态方法在几个派生对象类型中选择(我们称调度)正确实现的能力。答案 3 :(得分:0)
这与继承无关,可以简化问题并将方法PI_add
移至MainProgramSimply
。
non_Main_method
是实例(非静态)方法,它意味着它共享当前对象的状态,其所有实例成员如PI_add
方法
public void non_Main_method()
{
PI_add(); //-> No Object reference is required
}
是的,
无需对象引用
因为调用实例成员不需要在同一个类的另一个实例成员内的对象引用上调用,因为你将通过实例调用non_Main_method
(对吗?),您可以使用this
关键字,这意味着:在当前类实例上调用此成员:this.PI_add();
但您可以省略它,因为您总是为当前实例编写。< / p>
但另一方面,静态方法更可能是在类级别而不是实例级别上可访问的全局成员,因此当您想要调用实例成员时,您需要指定要在哪个实例上准确调用