"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
仅在您使用该显式类型时才有效。它基本上隐藏了链中的其他实现。因此,this
在 Base
的上下文中会给你 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?
的一个很好的答案
如果我有这样的东西:
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
仅在您使用该显式类型时才有效。它基本上隐藏了链中的其他实现。因此,this
在 Base
的上下文中会给你 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?