C# 为什么我可以使用类名而不使用类实例来调用这个静态方法? 类程序 { 静态void Main(字符串[]参数) { var p=新程序(); p、 Main(args);//实例引用错误,请改用类型名 var p=新程序(); Program.Main(args);//错误消失 } }

C# 为什么我可以使用类名而不使用类实例来调用这个静态方法? 类程序 { 静态void Main(字符串[]参数) { var p=新程序(); p、 Main(args);//实例引用错误,请改用类型名 var p=新程序(); Program.Main(args);//错误消失 } },c#,class,static-methods,method-call,member-access,C#,Class,Static Methods,Method Call,Member Access,我想我知道静态与对象实例无关,但我遇到的问题是类不是对象的同义词?或者在创建对象时不使用类?那么,如果类本质上是对象,那么当我使用类名时,为什么错误会消失呢 我知道我还没有创建Main的实例,也不会创建。这是唯一的区别吗?也许在我所学的这门课上没有正确地解释这一点。你的困惑是很自然的,C#在这方面的设计加剧了这种困惑。我会尽量解释一下,我会重新编排你的问题,以便更容易回答: 类与对象同义吗 不,让我们非常非常清楚这一点“对象”在C#中有特定含义。对象始终是类型的实例。C#中有两大类对象:通过引用

我想我知道静态与对象实例无关,但我遇到的问题是类不是对象的同义词?或者在创建对象时不使用类?那么,如果类本质上是对象,那么当我使用类名时,为什么错误会消失呢


我知道我还没有创建
Main
的实例,也不会创建。这是唯一的区别吗?也许在我所学的这门课上没有正确地解释这一点。

你的困惑是很自然的,C#在这方面的设计加剧了这种困惑。我会尽量解释一下,我会重新编排你的问题,以便更容易回答:

对象
同义吗

不,让我们非常非常清楚这一点“对象”在C#中有特定含义。对象始终是类型的实例。C#中有两大类对象:通过引用复制的引用类型,如
string
和通过值复制的值类型,如
int

稍后您将了解装箱,这是一种机制,通过该机制,可以在需要引用的上下文中使用值类型的实例,但现在不要担心这一点

在C#中,一个类定义了一个引用类型。该类的实例是对象。类本身不是对象

这样做的理由来自现实世界。“所有对象都是报纸”类本身不是报纸。“所有说法语的人”这门课本身并不是讲法语的。将一组事物的描述与该事物的特定示例混淆是一种类别错误

(您可能希望仔细检查原型继承语言(如JavaScript)的设计。在JS中,我们创建了一个特定的对象,它是一种事物的原型示例,我们创建了一个构造函数对象,它表示该事物的新示例的工厂;原型和构造函数一起工作,以创建新的inst它们都是真正的对象。但同样,你的问题是关于C#的,所以现在让我们坚持这一点。)

类是否用于创建对象

是的。我们用
new
实例化一个类;因为所有类都是引用类型,
new
生成对新对象的引用

那么,如果类本质上是对象,那么当我使用类名时,为什么错误会消失呢

类不是对象,但我理解您的困惑。它看起来确实像是在您期望对象的上下文中使用的类名。(您可能有兴趣仔细研究Python等语言的设计,其中类是对象,但您的问题是关于C的,所以让我们坚持这一点。)

要解决这一困惑,您需要了解C#中的成员访问操作符(也称为“点操作符”)是最灵活、最复杂的操作符之一。这使得它易于使用,但很难理解

需要了解的关键是,成员访问操作员始终具有以下形式:

  • 在点的左边是一个表达式,它的计算结果是一个有成员的对象
  • 在点的右边是一个简单的名字
  • 虽然
    thing
    是一个对象,
    thing.name
    是一个对象是可能的,也是常见的,但也有可能其中一个或两个都不是对象
当你说
p.Main
时,编译器会说“我知道
p
程序的一个实例,我知道
Main
是一个名称。这有意义吗?”

编译器要做的第一件事是验证
Program
-
p
的类型是否有一个可访问的成员
Main
,它就是这样做的。此时,重载解析开始起作用,我们发现
Main
的唯一可能含义是一个静态方法。这可能是一个错误,因为de>p
是一个实例,我们正试图通过该实例调用一个静态。C#的设计人员本可以允许这种情况——在其他语言中是允许的。但由于这可能是一个错误,他们不允许这样做

键入
Program.Main
时,
Program
不是对象。编译器验证
Program
是否引用了类型,并且类型是否有成员。重载解析再次接管,它确定唯一可能的含义是调用
Main
。因为
Main
是静态的,而接收者——点左边的东西——指的是一个类型,这是允许的

也许在我上的这门课上没有正确的解释

我编辑技术书籍和其他课程材料,其中许多对这些概念的解释非常糟糕。此外,许多讲师对类、对象、变量等之间的关系有模糊和混乱的概念。我鼓励您就这些问题向讲师提问,直到您对课程内容感到满意为止ir解释

也就是说,一旦你对这些问题有了坚实的理解,你就可以开始走捷径了。作为专业的C#程序员,我们说“
p
是一个对象,它是……”因为我们都知道我们的意思是“
p
是一个变量,它的值是对一个对象的引用,它是……”

我认为这对初学者来说是有帮助的,但是你会很快变得更加放松

还有一件事你没有问,但很重要:

反思呢

Type t = typeof(Program);
t.Main();