You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实例化类时如何引用父类的变量与属性?

问题描述

我已经能在C#中通过类似匿名类的方式扩展类并重写虚方法,但现在遇到一个问题:在这种场景下无法引用父类的类变量或属性。

简化后的父类代码:

public class MyAsyncBackgroundJob<TExecuteArgs> {

    public Func<TExecuteArgs, Task> ExecutePropAsync { get; set; }

    protected int _myVariable = 1;  // 示例变量
    public int MyProp { get; set; } = 2;  // 示例属性


    public MyAsyncBackgroundJob() {
    }

    public virtual Task ExecuteAsync(TExecuteArgs args) {
        return ExecutePropAsync(args);
    }
}

我期望的使用方式:

var myVar = new MyAsyncBackgroundJob<string> {
    ExecutePropAsync = (string s) => {
        string output = null;

        // 这段代码正常工作
        if (s == "example") output = s + s;

        // 编译报错:找不到_myVariable
        if (_myVariable == 1) output = s + s;

        // 编译报错:找不到MyProp
        if (MyProp == 1) output = s + s;

        return Task.FromResult(output);
    }
};

// 实际场景中ExecuteAsync会被框架自动调用
await myVar.ExecutePropAsync("example");

当前代码无法访问父类的_myVariable和MyProp,编译器提示未找到这些成员,求解决方法。

解决方法

方案1:捕获实例引用

放弃对象初始化器,先创建实例再给委托赋值,同时捕获实例本身,通过实例访问父类成员:

var myVar = new MyAsyncBackgroundJob<string>();
myVar.ExecutePropAsync = s => {
    string output = null;
    // 通过实例访问父类成员
    if (myVar._myVariable == 1) output = s + s;
    if (myVar.MyProp == 1) output = s + s;
    return Task.FromResult(output);
};

注意:对象初始化器执行时实例尚未完全初始化,无法直接在初始化器内引用自身,因此必须拆分创建和赋值步骤。

方案2:修改父类委托定义,传入实例参数

调整父类中ExecutePropAsync的委托类型,增加当前实例作为参数,在委托中通过该参数访问成员:

public class MyAsyncBackgroundJob<TExecuteArgs> {
    // 调整委托,增加当前实例参数
    public Func<MyAsyncBackgroundJob<TExecuteArgs>, TExecuteArgs, Task> ExecutePropAsync { get; set; }

    protected int _myVariable = 1;
    public int MyProp { get; set; } = 2;

    public virtual Task ExecuteAsync(TExecuteArgs args) {
        // 调用委托时传入当前实例
        return ExecutePropAsync(this, args);
    }
}

使用时通过第一个参数访问实例成员:

var myVar = new MyAsyncBackgroundJob<string> {
    ExecutePropAsync = (job, s) => {
        string output = null;
        if (job._myVariable == 1) output = s + s;
        if (job.MyProp == 1) output = s + s;
        return Task.FromResult(output);
    }
};

方案3:直接重写虚方法(替代委托方案)

如果核心需求是重写ExecuteAsync方法,直接用子类重写的方式,能自然访问父类成员,无需依赖委托:

// C# 10+支持局部类,避免污染全局命名空间
file class TempBackgroundJob : MyAsyncBackgroundJob<string> {
    public override Task ExecuteAsync(string args) {
        string output = null;
        // 直接访问父类成员
        if (_myVariable == 1) output = args + args;
        if (MyProp == 3) output = args + args;
        return Task.FromResult(output);
    }
}

var myVar = new TempBackgroundJob { MyProp = 3 };

这种方式既满足类似匿名类的临时扩展需求,又能正常访问父类的变量和属性。


内容的提问来源于stack exchange,提问作者Gianpiero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:55:29