[英]C# - Inside instance method, why can we access static members without using the class name?
This seems counter-intuitive to me. 这对我来说似乎违反直觉。 If we have a class Dog with static method CountAllDogs(), C# forbids to call it like this: myDog.CountAllDogs().
如果我们有一个具有静态方法CountAllDogs()的Dog类,则C#禁止这样调用它:myDog.CountAllDogs()。 (myDog is an object of type Dog).
(myDog是Dog类型的对象)。 But if we are inside an instance method Bark(), we can call it simply by using CountAllDogs().
但是,如果我们在实例方法Bark()中,则可以使用CountAllDogs()来简单地调用它。 Inside the instance method Bark(), the context ("this") is the object myDog, not the class itself, so I wonder why this is allowed?
在实例方法Bark()中,上下文(“ this”)是对象myDog,而不是类本身,所以我想知道为什么允许这样做吗?
"Why" questions are frequently vague, and this one is no exception. “为什么”的问题经常含糊不清,这一点也不例外。 Rather than answer your vague and confusing question, I'll answer a different question.
除了回答您的含糊和令人困惑的问题外,我将回答另一个问题。
What is the fundamental rule for resolving unqualified names in C#?
解决C#中不合格名称的基本规则是什么?
The fundamental rule of resolving an unqualified name is search from inside to outside . 解决不合格名称的基本规则是从内到外搜索 。 Suppose you have:
假设您有:
using System;
namespace A {
namespace B {
using C;
class D
{
public static void E() {}
}
class F : D {
public static void G() {}
public void H()
{
Action i = ()=>{};
Now suppose somewhere inside H
we have an unqualified name, X
. 现在假设
H
内的某个地方有一个不合格的名称X
We need to figure out what it means. 我们需要弄清楚这是什么意思。 So we go from inside to outside:
因此,我们从内到外:
(This is a sketch that leaves out a few details, such as how aliases are dealt with and so on; read the specification if you want the details.) (这是一个草图,其中省略了一些细节,例如如何处理别名等;如果需要这些细节,请阅读规格。)
An interesting point here is that base classes are considered to be "more inside" than the lexically containing program element . 这里有趣的一点是, 基类被认为比词法包含的program元素“更内部” 。 Members of D are considered to be members of F, so they must be checked before we check B.
D的成员被认为是F的成员,因此在检查B 之前必须先对其进行检查。
That's the fundamental rule. 这是基本原则。 There are also a few extra rules added for convenience.
为了方便起见,还添加了一些额外的规则。 For instance, if we had
X()
then only invocable members are considered when doing the search. 例如,如果我们有
X()
则在进行搜索时仅考虑可调用成员。 There is also the famous "Color Color" rule, which says that if you have a type called Color and a property of type Color called Color -- because what else would you call it? 还有一条著名的“颜色颜色”规则,该规则表示,如果您有一个名为Color的类型和一个名为Color的Color类型的属性,那么您还会调用它吗? -- then the name lookup rules for Color are smart about figuring out whether you meant the type or the property, even when that means departing from the fundamental rule of unqualified name lookup.
-那么Color的名称查找规则很聪明,可以弄清楚您是指类型还是属性,即使这意味着脱离了不合格名称查找的基本规则。
Now that you know the fundamental rule you can apply it to your situation. 现在您已经知道了基本规则,可以将其应用于您的情况。 Why can you call a static member without qualification?
为什么您可以不加资格地致电静态会员? Because the fundamental rule of unqualified name lookup is "search from inside to outside", and doing so finds a static element with that name .
因为不限定名称查找的基本规则是“从内到外搜索”,所以查找具有该名称的静态元素 。 If we're inside
H
and we have G()
then G
is not a local but it is an invocable member of the enclosing class, so it wins. 如果我们在
H
并且有G()
则G
不是局部变量,但它是封闭类的可调用成员,因此它赢了。 If we're inside H
and we have E()
then we find it in D
, after failing to find it in H
or F
. 如果我们在
H
并且有E()
那么在H
或F
找不到它之后,就可以在D
中找到它。 And so on. 等等。
When you call an unqualified instance member, same thing. 当您调用不合格的实例成员时,同样的事情。 The unqualified name is resolved, and if it turns out to be an instance member , then
this
is used as the receiver of the member. 解析了不合格的名称, 如果结果是实例成员 ,则将
this
用作该成员的接收者。
To call an instance-member you need an instance of course. 要调用实例成员,您当然需要一个实例。 In case you´re allready within an instance-member you can of course use the
this
-reference, which points to the current instance. 如果you're媒体链接的情况下,构件内 ,当然你可以使用
this
引用,它指向当前实例。 If you´re on the other side calling your instance-member from outside your class you´d write something like this: 如果您从另一面从类外部调用实例成员,则应编写如下内容:
myInstance.DoSomething();
So actually using this
as qualifier is redundant, you may simply omit it if you´re within the method. 因此, 实际上将
this
用作限定符是多余的,如果您在方法内 ,则可以简单地忽略它。
A static member doesn´t know any instance, thus no this
. 静态成员doesn't知道任何情况,因此没有
this
。 Adding the class´-name is again redundant information as adding the this
-keyowrd to an instance-member. 再次添加类名是多余的信息,因为
this
-keyowrd添加到实例成员。
The compiler should be clever enough to determine that a member is static or not and thus if or of not he needs an instance. 编译器应该足够聪明,可以确定一个成员是否是静态的,从而确定他是否需要一个实例。
Personally I agree that adding the context in which a member might be invoked is a good thing, which is even forced in Java eg This avoids anoying prefixes on variables such as m_
for instance- and s_
for static members. 我个人同意,添加可以在其中调用成员的上下文是一件好事,这在Java中甚至是强制执行的,例如,这避免了烦恼诸如
m_
表示实例的前缀和s_
表示静态成员的变量。 But again the compiler allready knows, it´s just a matter of taste. 但是,编译器已经知道了,这只是个问题。
So having said this there´s no actual need why this should or should not be permitted as it doesn´t avoid any mistakes not produces any. 所以说了这一点并没有实际的必要,为什么应该或不应该这样做,因为它不能避免任何错误,因此不会产生任何错误。 It´s just a convention-thing to be more strict.
这只是一个约定,要更加严格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.