C#面试必问:this和base的底层原理与应用详解
C#面试题千千万“简述this和base的作用”绝对是出场率最高的那一批。我在面试候选人时常用它来摸底——别以为它是送分题我见过不少简历上写着“熟悉C#”的人一上来能背出“this指向当前对象、base指向父类”但追问到构造函数初始化器、扩展方法里的this、base调用虚方法时是否触发多态眼神就开始发虚。这篇文章就用手把手的方式把这套面试题背后的原理、代码、坑点和进阶答法一次讲透适合准备C#岗位面试的求职者也适合日常跟WinForm、上位机打交道的业务开发把这两个关键字理解透实打实能帮你少踩雷。1. 面试官问this和base到底想考察什么1.1 一道基础题为什么淘汰率不低很多候选人把这道题当热身题觉得“this就是当前对象base就是父类”背出来就完事。可作为一个面试官我最怕的就是这种照本宣科的答案。这道题之所以经典是因为它牵涉到四个语法层面的知识构造函数链、成员隐藏、继承与多态、扩展方法。就问一句话能探测出候选人写代码时对这四件事到底有多熟。我面试过不少有两三年工作经验的开发者真正让人满意的回答往往是这样的开头“this和base本质上都要在当前实例上操作this是给当前实例用的完整引用base则是告诉编译器去调用基类那一套实现。”能说出“基类的实现”而不是“父类对象”说明他是从底层机制去理解的这种候选人在后续的追问里也基本不会垮掉。相反只会背概念的人写到构造函数时一旦出现this(...)和base(...)就分不清该用哪个项目里真出问题也完全无从下手。1.2 三档答案对应三种认知层次我把这道题的现场回答分成三档你可以自己对号入座看看目前在哪一档及格档“this指向当前对象base指向父类对象。”能背出定义但被追问构造函数重载里的this(...)或base(...)用法时会愣住解释不清为什么两者不能同时用。过关档知道this能区分同名参数和字段、能链式调用自身构造函数知道base能调用基类构造函数、调用被隐藏的基类方法也知道this和base都不能出现在静态方法里。满分档能说清base并不是创建了父类对象而是在当前对象上调用基类实现能区分base.M()和this.M()在多态上的行为差异能主动提到扩展方法中this的本质还能指出结构体里只有this没有base。这篇文章后面所有小节就是在手把手教你从及格档走到满分档。2. this的作用全解从本质到三个高频用法2.1 this的本质实例方法里的隐藏参数先说点硬核的在C#编译后的IL层面普通的实例方法并不是“没有参数”的它默认藏了一个指向当前实例的引用也就是this。你在方法体里写this.name编译器才能明确这个name到底属于哪个对象。CLR在调用实例方法时会把这个引用作为隐藏参数压栈所以方法内部天然知道自己属于哪个实例。用生活里的例子类比你在朋友圈发个“我”朋友看到就知道是“你本人”代码里的this也一样它把“当前这个对象”指了出来。这个细节在面试时很加分因为你可以顺着说静态方法不依附于某个具体实例所以静态方法里没有this静态构造函数里也不能用this。这比单纯背定义高一个层次。2.2 高频用法一区分字段与构造参数这是this最基础的用法当构造函数的参数名和类字段重名时用this告诉编译器“我指的是成员字段不是参数”。像下面这样public class Person { private string name; private int age; public Person(string name, int age) { this.name name; this.age age; } }如果没有this前缀name name就变成了自己给自己赋值字段永远没被正确初始化。这个问题在大型业务类里特别容易埋雷尤其是字段多、构造函数参数多的时候。我在代码审查时看到有人漏写this导致数据对不上的bug已经不止一次了。2.3 高频用法二this(...)让构造函数链起来构造函数重载多起来之后如果每个构造函数都单独写一遍初始化逻辑代码会膨胀得很厉害。这时候可以用this(...)在构造函数初始化器位置调用本类的另一个构造函数让所有构造都汇聚到参数最完整的那一个public class Order { private string id; private decimal amount; private DateTime createdAt; public Order(string id) : this(id, 0m, DateTime.Now) { } public Order(string id, decimal amount) : this(id, amount, DateTime.Now) { } public Order(string id, decimal amount, DateTime createdAt) { this.id id; this.amount amount; this.createdAt createdAt; } }这样做的好处是初始化逻辑只写一遍以后新增必填字段时只需改那个“主构造函数”。但也要注意this(...)和base(...)只能出现在冒号后面的初始化器位置不能在构造函数体里调用另一个构造函数——那会变成创建第二个对象而不是初始化当前对象。2.4 高频用法三返回this实现流式接口this的另一个常见用法是作为方法的返回值返回当前实例方便调用方用链式语法连续调用。这在很多框架的Builder模式里非常常见public class ReportBuilder { private string title; private string content; public ReportBuilder SetTitle(string title) { this.title title; return this; } public ReportBuilder SetContent(string content) { this.content content; return this; } public Report Build() { return new Report(title, content); } }调用起来就是var report new ReportBuilder() .SetTitle(月报) .SetContent(本月数据) .Build();这种写法让调用方阅读起来很顺畅不用一行一个变量来回赋值。注意返回this的前提是方法本身就定义在实例类上静态方法做不到。另外如果你在做上位机开发代码里常见的this.BeginInvoke(...)也是拿当前窗体实例去执行跨线程UI更新本质是一样的——把当前对象作为调用的主体。3. base的作用全解基类访问的正确姿势3.1 base的本质不是父类对象是基类实现很多新手对base有个误解以为base指向的是“父类创建出来的另一个对象”。实际上继承体系里子类对象和父类共享同一个内存实例并不存在两个独立的对象。base关键字在这里更像一个“语法入口”告诉编译器在当前这个对象上去调用基类定义的那个成员而不是子类覆盖后的版本。类比一下父类是“一身厨艺的师傅”子类是“看了师傅菜谱的徒弟”。徒弟调用base.Cook()并不是另外请一个师傅来炒菜而是徒弟自己按师傅的菜谱炒了一锅人还是那个人只是方法来源不同。这个理解非常关键因为它直接影响到下一节里的多态问题。3.2 高频用法一base(...)调用基类构造派生类构造函数默认会隐式调用基类的无参构造函数但如果基类只有带参构造函数或者你想把参数传给基类做初始化就必须用base(...)显式指定public class Employee : Person { private string department; public Employee(string name, string department) : base(name) { this.department department; } }这里base(name)就是把name传给基类Person的构造函数让基类先完成自己那部分字段初始化再回到子类构造函数继续处理department。实际项目里最常见的坑是基类加了带参构造函数之后忘了给子类改构造函数签名编译直接报错“Person不包含采用0个参数的构造函数”遇到这个报错基本就是base(...)没接好。3.3 高频用法二base.方法()调用被覆盖的基类实现子类重写或隐藏了基类方法后如果想在这个方法里保留基类的原始逻辑再用base.方法()把基类实现拉回来。典型的模式是这样public class Animal { public virtual void Speak() { Console.WriteLine(Animal speaks); } } public class Dog : Animal { public override void Speak() { Console.WriteLine(Dog barks); base.Speak(); // 保留基类原始行为 } }这种写法在框架开发里非常常见比如你重写OnLoad、OnClosing这类生命周期方法时几乎总是在方法开头或结尾调用base.OnLoad(e)来确保框架默认逻辑不被破坏。很多人一开始不理解为什么必须调用base总觉得不写也无所谓直到某些资源没释放、界面状态没恢复时才反应过来。3.4 不能忽视的三个边界条件使用base有三个边界条件我建议你在面试时主动说出来这是加分项第一base只能在派生类的实例成员中使用静态方法、静态构造函数里不能用结构体里也不能用因为struct没有继承体系不存在基类这个概念。第二base只能访问“直接基类”的成员不能跨级访问“爷爷类”。比如类A是B的基类B是C的基类在C里写base.SomeMethod()只能找到B的版本想调用A的实现得由B先暴露一个转发方法C再通过base调用B的转发方法。第三基类私有成员对子类不可见所以即使写了base.PrivateMember()也会编译报错这跟继承无关就是访问权限规则。把这三个边界条件讲清楚面试官基本能确认你是真在面向对象编程里摸爬滚打过的人。4. this和base的区别与坑点一张表加三个实战案例4.1 一张表看懂this和base的差异先给一张常用对比表方便记忆也方便面试时回答“两者有什么区别”对比维度thisbase语义当前实例的引用在派生类中访问直接基类成员的语法入口使用位置实例成员、索引器声明、构造函数初始化器派生类的实例成员、构造函数初始化器静态方法中不能使用不能使用结构体中可以使用this区分成员不能使用构造函数初始化器this(...)调用同类构造函数base(...)调用基类构造函数调用虚方法正常多态分派绕过虚分派调直接基类实现多层继承始终指向当前实例只能触及直接基类扩展方法可作为静态方法第一个参数不能使用这张表里最容易被忽略的是“调用虚方法”那一行下面单独展开说这也是面试中最高频的追问点。4.2 为什么构造函数初始化器不能同时用this和base很多人背过“构造函数初始化器里this(...)和base(...)不能同时使用”但没想过原因。其实很简单冒号后面的初始化器只能有一个入口——要么你选择把初始化接力棒交给同一个类里的另一个构造函数要么交给基类的构造函数不可能同时交给两个对象完成初始化。看这个示例public class B : A { public B(int x) : this(x, 0) { } public B(int x, int y) : base(x) { } }第一个构造函数通过this(x, 0)链到第二个构造函数第二个构造函数再通过base(x)链到基类A的构造函数。这里this链和base链是一条线串起来的而不是在同一层同时出现的。如果写成base(x), this(...)会直接编译报错因为编译器根本不接受这种组合。现实中如果发现初始化逻辑在两个构造函数里重复优先用this链汇聚让最终那个主构造函数去对接base。4.3 base.M()和this.M()多态行为完全不同这是我每次面试必追的一个点也是很多工作两三年的人最容易翻车的地方。看下面这段代码public class A { public virtual void M() { Console.WriteLine(A.M); } } public class B : A { public override void M() { Console.WriteLine(B.M); base.M(); // 这里会输出 A.M } } public class C : B { public override void M() { Console.WriteLine(C.M); base.M(); // 这里会输出 B.M不是 A.M // 如果这里写 this.M()会递归调用 C.M 自己直到栈溢出 } }注意base.M()在C里的行为C的直接基类是B所以base.M()调用的是B.M而B.M内部的base.M()才调用A.M。这个链条是逐级向上的不是直接跳到最顶层。反过来如果在C的M方法里写this.M()因为this始终是当前实例虚方法表会重新分派到C.M自己于是C.M内部无限调用自身栈溢出只是时间问题。从IL层面看base.M()会编译为call指令直接指定调用基类的那个方法实现this.M()则编译为callvirt指令按运行时真实类型去做虚分派。这个区别解释了为什么在重写方法里想保留父类逻辑一定得用base而不是this。这个坑我在代码评审里见过不止一次新人特别容易犯。5. 进阶追问扩展方法、虚方法、索引器里的this/base5.1 扩展方法里的this静态方法变“实例方法”的糖衣面试官稍一进阶就会问扩展方法里的this是怎么回事这个问题能筛掉一批只背概念的人。扩展方法本质是静态方法但它的第一个参数前面可以加this修饰调用时看起来就像在实例方法public static class StringExtensions { public static bool IsNotEmpty(this string s) { return !string.IsNullOrEmpty(s); } }调用时你写text.IsNotEmpty()但编译器实际生成的调用是StringExtensions.IsNotEmpty(text)。它把这个实例当成普通参数传给了静态方法这就是为什么扩展方法必须定义在静态类里而且this只能修饰第一个参数。顺带一提扩展方法的this参数不能用ref和out修饰这也是规范限制。如果能把这个讲清楚面试官对你这道题的印象会立刻改观因为大多数人根本不会主动联想到扩展方法。5.2 索引器、WinForm异步与lambda捕获中的this索引器也是this的一个特殊用法。定义索引器时语法就是this[int index]这里的this是C#固定的语法符号不能换成别的名字。它让对象可以被obj[0]这样访问本质上编译后会生成get_Item和set_Item方法public class StringCollection { private string[] items new string[10]; public string this[int index] { get items[index]; set items[index] value; } }在WinForm和上位机开发里this最常见的场景其实是跨线程更新UI。比如后台线程读取仪表数据回来刷新界面典型写法是private void OnDataReceived(string data) { if (this.InvokeRequired) { this.BeginInvoke(new Actionstring(OnDataReceived), data); return; } this.lblValue.Text data; }这里的this是当前窗体实例它既用来判断线程是否安全也用来封送调用。但要注意lambda表达式对this的捕获问题如果你在Task.Run里使用this.xxx等于把整个窗口实例捕获到了后台任务里窗体关闭但任务还在运行就可能访问已释放的控件。面试时主动提一句“this在闭包里会被捕获使用时要考虑对象生命周期”这能体现出你踩过坑、有实战经验。5.3 面试官喜欢追问的两道变形题这道题常见的变形题有两个我建议你都准备好第一道“静态方法里能用this和base吗”答案是都不能。静态成员没有实例上下文this没有对象可以指向base也没法调用实例基类成员。第二道“base能访问爷爷类的成员吗”不能base只面向直接基类。想访问爷爷类的成员需要在直接基类里提供一个转发方法一层一层传上去。第三道往往跟着来“结构体里能用base吗”答案是不能结构体是值类型没有继承体系但结构体能使用this来区分成员只是不能出现在构造初始化器链式调用里。能把这几个变形题答出来这道面试题基本就满分了。5.4 一段能拿高分的现场回答模板如果你需要一个可以直接用的回答骨架我建议这样组织语言“this是当前实例的引用base是在派生类中访问直接基类成员的语法入口。this常用于区分同名参数和字段、链式调用构造函数、返回当前对象实现流式接口base常用于调用基类构造函数、在重写或隐藏的方法里调用基类实现。两者都不能在静态成员中使用构造函数初始化器里this(...)和base(...)二选一。区别在于this调用虚方法仍然走虚分派base调用虚方法则绕过虚分派直接调直接基类的实现。此外扩展方法里this出现在静态方法第一个参数位置本质是编译器把实例调用转写成静态方法调用。”这段话不是让你死背而是掌握里面的逻辑每一条你都能用自己的代码举出例子现场就不会心虚。6. 业务代码里的this/base实操心得与面试建议6.1 构造函数重载多怎么办让this链朝一个方向汇聚我把这个原则写进过不少项目规范构造函数初始化链路尽量朝“参数最全那个构造函数”汇聚最终那个主构造函数再接base。这样新增必填字段时只需要改一处也不会出现六个构造函数各写各的初始化逻辑、互相不一致的情况。代码审查时如果看到this(...)和base(...)混在多个构造函数里绕来绕去我通常建议重构否则改需求的时候很容易改一处漏一处。6.2 参数命名与this取舍我的个人习惯在模型类、DTO类里我习惯参数名与字段保持一致然后统一用this.xxx xxx这样读代码的人一眼就能看出“虽然同名但左边是字段右边是参数”。在复杂业务方法里我则尽量让参数名避开成员名因为那些方法里this前缀太频繁反而显得啰嗦。你可以有自己的一套习惯但关键是团队里保持一致否则每个人写出来风格都不同代码维护成本会上升。6.3 给准备面试的人的一句话建议这道题能答到什么程度基本能反映你平时写代码时对这个语言特性的敏感度。与其把精力花在背“this当前对象、base父类”这种口号上不如自己创建一个Animal-Dog-Cat三层的继承结构再写一个构造函数重载多的模型类亲手跑一遍base.M()和this.M()亲眼看一次栈溢出比背十遍定义都管用。真面试时被追问到不熟的地方诚实说“平时很少用base”也比硬编答案要强面试官更愿意看到你推理问题的过程而不是背诵的熟练度。我自己带人时经常说基础语法就像地基里的钢筋平时不显眼遇到问题的时候才知道谁家的地基牢靠。

相关新闻

基于Java与Spark2x的新闻大数据实时分析可视化系统实战

基于Java与Spark2x的新闻大数据实时分析可视化系统实战

简介:这份资源是面向高校课程设计与大数据入门者的完整项目包,主题为基于Java与Spark2x构建新闻网大数据实时分析与可视化系统,适合需要完成综合性大数据作业或希望打通实时处理链路的开发者。包内共36个文件,以10个jar依赖、7个s…

2026/10/12 1:56:04 阅读更多 →
大模型性价比评估实战:从成本拆解到迁移落地的完整方法论

大模型性价比评估实战:从成本拆解到迁移落地的完整方法论

1. 从"性能比肩、成本六折"说起:这个标题到底在讲什么第一次看到"性能比肩、成本六折"这个说法,我的第一反应不是兴奋,而是习惯性地去找它的比较基准。任何一句关于模型性能的论断,如果不把"跟谁比、在什…

2026/10/12 1:38:40 阅读更多 →
无人机俯视车辆行人检测:VisDrone数据集YOLOv5训练与避坑指南

无人机俯视车辆行人检测:VisDrone数据集YOLOv5训练与避坑指南

简介:无人机俯视视角下的车辆与行人目标检测数据集,面向目标检测算法研发人员与相关专业学习者,专为YOLO系列模型快速迭代而整理。资源包含一千多张无人机实拍俯视图像,所有样本均标注车辆与行人两类目标,可应用于智慧…

2026/10/12 1:56:12 阅读更多 →

最新新闻

Vue实战进阶:从环境配置到动态路由与多端部署要点

Vue实战进阶:从环境配置到动态路由与多端部署要点

学Vue这几年,从最开始只会照着教程敲todo list,到后来完整负责过好几个基于Spring Boot加Vue的前后端分离项目,中间踩过的坑、绕过的弯,攒下来不少东西。这份Vue网站制作学习心得,我按“从入门到实战的进阶之路”来写&…

2026/10/12 13:21:33 阅读更多 →
豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

简介:这份资源是面向高校学生与Python初学者的数据可视化课程设计完整方案,围绕豆瓣电影Top250数据集展开,涵盖数据采集、清洗、统计分析与图表呈现全流程,适合用作毕业设计、期末大作业或课程设计的高分参考。压缩包共221个文件&…

2026/10/12 13:21:33 阅读更多 →
基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

每年到这个时间点,都会有一批学弟学妹来问我:"毕设选题到底怎么选?Java后端会不会太难?前端是不是要写很多页面?"我的回答一直很统一:如果方向是Java Web或全栈开发,基于SpringBoot …

2026/10/12 13:21:33 阅读更多 →
claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

你有没有过这种体验:跟Claude聊一个项目,前期费了好大劲把背景、依赖、约束讲清楚,刚进入正题,上下文窗口满了,或者新开一个会话,全部打回原形。每次对话就像金鱼一样,七秒记忆,项目…

2026/10/12 13:21:33 阅读更多 →
云数据库HTTP API歌单更新实战:权限、批量与避坑指南

云数据库HTTP API歌单更新实战:权限、批量与避坑指南

1. 从一次歌单同步的诡异失败说起做云音乐类小程序,绕不开的一个核心功能就是歌单管理。用户在小程序端新建、编辑、删除歌单,这些操作最终都要落到云数据库里。我最近在重构一个云音乐小程序的管理系统,前面几篇已经把基础架构、页面路由、用…

2026/10/12 13:21:33 阅读更多 →
C++中判断汉字:从编码原理到跨平台实现

C++中判断汉字:从编码原理到跨平台实现

1. 从一次文本统计翻车说起:为什么“判断汉字”没那么简单前阵子帮一个做数据清洗的朋友处理一批用户提交的文本,需求听起来特别朴素:把每条记录里的汉字挑出来,统计一下字数,非汉字的字符(标点、数字、字母…

2026/10/12 13:20:31 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →