"this" 在从基础 class 派生 class 的对象上调用时的关键字类型

"this" keyword type when called on an object of derived class from base class

如果我有这样的东西:

class Base
{
    public void Write()
    {
     if (this is Derived)
      {
         this.Name();//calls Name Method of Base class i.e. prints Base
        ((Derived)this).Name();//calls Derived Method i.e prints Derived 
      }
     else
      {
        this.Name();
      }
    }

    public void Name()
    {
        return "Base";
    }
}

class Derived : Base
{
    public new void Name()
    {
        return "Derived";
    }
}

并使用下面的代码调用它,

Derived v= new Derived();
v.Write(); // prints Base

然后调用基础 class 的 Name 方法。但是 Write 方法中 this 关键字的实际类型是什么?如果那是 Derived 类型(因为程序控件进入 Write 方法中的第一个 if 块)那么它正在调用基础 Name 方法,为什么要显式转换,(Derived)this,改调用derived的Name方法class?

this 将始终是派生的 class 类型。

之所以在调用this.Name();中调用基础className()方法是因为Name没有定义为虚方法,所以被链接在编译时,当编译器不知道此时 this 的实际类型时。

关于上面的代码还有一个注意事项。通常在产品代码中,从 Base class 明确引用 Derived class 确实是一种不好的做法,因为它违反了 Base class 不应该知道的 OOP 原则之一 classes 继承了它。但是,假设上面的代码只是用于 C++ 调查,那么这当然没问题。

如果你想访问派生的任何被覆盖的成员,你应该使用 virtual 和 override class:

class Base
{
    public void Write()
    {
     if (this is Derived)
      {
         this.Name();//calls Name Method of Base class i.e. prints Base
        ((Derived)this).Name();//calls Derived Method i.e prints Derived 
      }
     else
      {
        this.Name();
      }
    }

    public virtual void Name()
    {
        return "Base";
    }
}

class Derived : Base
{
    public override void Name()
    {
        return "Derived";
    }
}

通过转换 ((Derived)this).Name(),您明确地将其设置为派生的 class。由于您在基 class 中定义了 Write,这会将方法调用指向它。出现此行为是因为您没有重写基本方法,而是从基本方法 class.

调用它

这就是您所需要的。您不需要也不应该从基础检查类型来处理逻辑。任何特殊逻辑都应在派生的 classes 中处理,并且可能希望在基础中将方法标记为 virtual,在派生的 classes 中将方法标记为 override

class Base
{
    public void Write()
    {
        SomeWriteMethod(Name());
    }

    public virtual void Name()
    {
        return "Base";
    }
}

class Derived : Base
{
    public override void Name()
    {
        return "Derived";
    }
}

如果你想要 Name() 中的 class 的实际名称,你只需要在基础中调用 GetType().Name 它会自动为任何派生的 classes as GetType() returns 你是实例的实际实例类型。就像 GetType() 是实际实例一样,this 也是您的实际实例,因此任何特殊逻辑都将是 class 的实现。

this实际上是你基地class中的一个冗余调用。无论您指定它还是不指定它,您都会得到相同的结果。您看到混合结果的原因是因为您使用了 new 运算符。 new 仅在您使用该显式类型时才有效。它基本上隐藏了链中的其他实现。因此,thisBase 的上下文中会给你 Base.Name() 的地方,就好像你已经覆盖了,Derived.Name() 会被使用。

MSDN: Knowing when to use override and new keywords

这是关于 new -- Why does calling a method in my derived class call the base class method?

的一个很好的答案