C# Base关键字详解:访问基类成员与构造函数调用
C# 中的 base 关键字用于从派生类中访问基类的成员,主要应用于通过显式调用绕过虚方法重写机制以及初始化基类构造函数。与 this 关键字指向当前实例不同,base 指向父类实例,需注意其无法访问静态或抽象成员。
访问基类实例成员
base 关键字最基础的用法是通过 base.标识符 的形式访问基类的非静态成员。这常用于在派生类中调用被隐藏的基类成员,或在重写虚方法后调用原始实现。
第1步:理解 base 访问的非虚与虚方法差异
在使用 base 访问方法时,其行为取决于目标方法是否声明为 virtual:
1. 非虚方法: base.F() 是直接访问,等价于将当前对象强转为基类后调用 ((base)this).F()。
2. 已重写的虚方法: 即使使用 base.F(),也会跳过虚方法调用机制,直接执行基类的代码实现,此时不等价于 ((base)this).F()(后者仍会触发多态指向子类的重写版本)。
3. 未重写的虚方法: 行为等同于非虚方法,正常访问。
以下为详细测试代码,展示了在非虚方法、已重写虚方法、未重写虚方法以及索引器操作中的具体表现:
using System;
namespace BaseTest
{
class father
{
string str1 = "this field[1] of baseclass", str2 = "this field[2] of baseclass";
// 非虚方法
public void F1()
{
Console.WriteLine(" F1 of the baseclass");
}
// 虚方法 - 子类重写
public virtual void F2()
{
Console.WriteLine(" F2 of the baseclass");
}
// 虚方法 - 子类未重写
public virtual void F3()
{
Console.WriteLine(" F3 of the baseclass that is not overrided ");
}
// 索引器操作
public string this[int index]
{
set
{
if (index==1 )
{
str1 = value;
}
else
{
str2 = value;
}
}
get
{
if (index ==1)
{
return str1;
}
else
{
return str2;
}
}
}
}
class Child:father
{
public void G()
{
Console.WriteLine("======Non-virtual methods Test =========");
base.F1(); // 输出: F1 of the baseclass
((father)this).F1(); // 输出: F1 of the baseclass
Console.WriteLine("======virtual methods Test=========");
base.F2(); // 绕过重写,输出: F2 of the baseclass
((father)this).F2(); // 遵循多态,输出: F2 of the subclass
base.F3(); // 未重写,输出: F3 of the baseclass that is not overrided
((father)this).F3(); // 未重写,输出: F3 of the baseclass that is not overrided
Console.WriteLine("=====Test the type that the tbase [[expression]] ==========");
Console.WriteLine(base[1]); // 输出: this field[1] of baseclass
base[1] = "override the default ";
Console.WriteLine(base[1]); // 输出: override the default
Console.WriteLine("================Test Over=====================");
}
public override void F2()
{
Console.WriteLine(" F2 of the subclass ");
}
static void Main(string[] args)
{
Child child=new Child();
child.G();
Console.ReadKey();
}
}
}
在构造函数中调用基类
在派生类的构造函数定义中,可以使用 : base(...) 来明确指定要调用的基类构造函数及其参数。这要求基类必须存在匹配签名(参数数量和类型)的构造函数。
第2步:通过 base 匹配基类构造函数形参
当基类包含多个重载构造函数时,派生类可以通过这种方式精确控制初始化顺序。如果省略 base(...),编译器通常会尝试寻找并调用无参的基类构造函数;若不存在则编译报错。
using System;
namespace BaseCoTest
{
class Base
{
public Base(int a, string str)
{
Console.WriteLine("Base. Base(int a,string str)");
}
public Base(int a)
{
Console.WriteLine("Base. Base(int a)");
}
public Base()
{
}
}
class Sub : Base
{
public Sub()
{
}
// 显式调用带参数的基类构造函数
public Sub(int a)
: base(1, "123")
{
Console.WriteLine("Sub .Sub(int a)");
}
class Test
{
public static void Main()
{
Sub sub = new Sub(1);
// 预期输出:
// Base. Base(int a,string str)
// Sub .Sub(int a)
Console.ReadKey();
}
}
}
}
注意事项与限制
- 静态成员不可访问: base 关键字只能在实例上下文中使用,严禁用于访问基类的 static 字段、方法或属性。
- 抽象成员: 虽然 abstract 通常与虚函数配合,但 base 不能用于实例化基类的抽象成员,只能调用已实现的逻辑。
- 构造函数位置: base(...) 作为构造函数修饰符,必须位于派生类构造函数参数列表之后、函数体之前。
总结
C# 的 base 关键字是处理类继承关系的有力工具。它不仅允许我们通过 base.[member] 形式直接干预虚方法的多态行为,确保调用到原始的基类实现,还通过在构造函数中使用 : base(params) 精确管理对象初始化流程。正确区分 base 与 this,以及理解其在虚方法调用中的“静默”特性,对于编写健壮的面向对象代码至关重要。
以上就是C#中Base关键字访问基类成员及构造函数的详细内容,更多关于C#进阶基础知识的相关资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













