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

能否为C#属性的Getter和Setter设置默认函数?

在C#中为属性批量实现带IsDirty逻辑的Setter

C#本身不支持直接给类设置全局默认的Getter/Setter逻辑,但可以通过以下几种方案避免重复编写判断值变化、更新IsDirty的代码:

1. 基类封装通用Setter方法

创建一个包含通用设置逻辑的基类,子类的属性Setter直接调用基类方法即可:

public class DirtyTrackingBase
{
    public bool IsDirty { get; private set; }

    protected bool SetProperty<T>(ref T backingField, T value)
    {
        if (!EqualityComparer<T>.Default.Equals(backingField, value))
        {
            backingField = value;
            IsDirty = true;
            return true;
        }
        return false;
    }
}

子类使用示例:

public class MyClass : DirtyTrackingBase
{
    private string _property1;
    public string Property1
    {
        get => _property1;
        set => SetProperty(ref _property1, value);
    }

    private int _property2;
    public int Property2
    {
        get => _property2;
        set => SetProperty(ref _property2, value);
    }

    // 其余近100个属性都可以照此格式编写
}

2. T4模板批量生成代码

如果属性数量极多,可以用T4模板自动生成所有属性的完整代码,无需手动重复编写Setter逻辑:

创建一个名为MyClassGenerator.tt的文件,内容如下:

<#@ template language="C#" #>
<#@ output extension=".cs" #>
using System.Collections.Generic;

public class MyClass
{
    public bool IsDirty { get; private set; } = false;

<#
// 这里列出所有属性的类型和名称
var properties = new[] {
    new { Type = "string", Name = "Property1" },
    new { Type = "string", Name = "Property2" },
    new { Type = "int", Name = "Property3" },
    // 继续添加剩余属性...
};
foreach (var prop in properties) {
    var backingField = "_" + prop.Name.ToLowerInvariant();
#>
    private <#= prop.Type #> <#= backingField #>;
    public <#= prop.Type #> <#= prop.Name #>
    {
        get => <#= backingField #>;
        set
        {
            if (!EqualityComparer<<#= prop.Type #>>.Default.Equals(<#= backingField #>, value))
            {
                <#= backingField #> = value;
                IsDirty = true;
            }
        }
    }

<# } #>
}

保存后,Visual Studio会自动生成对应的.cs文件,包含所有属性的完整实现。

3. 编译时源生成器(C# 9+)

对于追求编译时性能的场景,可以使用C#源生成器,通过自定义特性标记需要跟踪的属性,自动生成Setter逻辑:

首先定义特性:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class TrackDirtyAttribute : Attribute
{
}

然后编写源生成器(需创建单独的类库项目),监听带有[TrackDirty]的属性,自动生成包含IsDirty更新逻辑的Setter代码。这种方式无需运行时反射,性能最优。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:20:49