Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Feature] Add value sanitizers to [ObservableProperty]

未关闭
#1,067 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
25/100
Issue 类型
功能
描述清晰度
需要澄清
活跃度
停滞
技术栈
csharp
领域
tooling

调研方向

从 [ObservableProperty] 源代码生成器及其生成的 setter 开始,并以此 issue 中的示例作为行为基准。首先确定 sanitizer API、支持的操作以及 setter/getter 的作用范围;当达成一致的设计支持所请求的 sanitizer 用例,并且生成的属性能正确应用这些操作时,即视为完成。

由索引模型根据 Issue 内容生成。

描述

feature request :mailbox_with_mail:
Overview

In many of my properties I must Clamp, Round, Max or Min the setter value.
This auto defeats the [ObservableProperty] which make me implement the raw property.
Example:

public double TimeoutSeconds
{
    get;
    set => SetProperty(ref field, Math.Round(
        Math.Clamp(value, 0, 10000),
        2,
        MidpointRounding.AwayFromZero)
    );
} = 5000;

Example of what I would like:

[ObservableProperty]
[ObservablePropertySetterClamp(0, 10000)]
[ObservablePropertySetterRound(2, MidpointRounding.AwayFromZero)]
public partial double TimeoutSeconds { get; set; }
API breakdown

Not sure how to make the API but I provide a sample of generated code:

[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.4.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public partial global::System.Double TimeoutSeconds
{
    get => field;
    set
    {
        // The new sanitizer magic here
        value = Math.Clamp(value, 0, 10000);
        value = Math.Round(value, 2, MidpointRounding.AwayFromZero);
        // End

        // Current implementation, unchanged.
        if (!global::System.Collections.Generic.EqualityComparer<global::System.Double>.Default.Equals(field, value))
        {
            OnLastExecutedDateTimeChanging(value);
            OnLastExecutedDateTimeChanging(default, value);
            field = value;
            OnLastExecutedDateTimeChanged(value);
            OnLastExecutedDateTimeChanged(default, value);
            OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.LastExecutedDateTime);
        }
    }
}
Usage example
[ObservableProperty]
[ObservablePropertySetterClamp(0, 10000)]
[ObservablePropertySetterRound(2, MidpointRounding.AwayFromZero)]
public partial double TimeoutSeconds { get; set; }
[ObservableProperty]
[ObservablePropertySetterMin(0)]
public partial int LapCount { get; set; }
[ObservableProperty]
[ObservablePropertySetterStringTrim]
[ObservablePropertySetterStringUpperCase]
public partial string Country { get; set; }
[ObservableProperty]
[ObservablePropertySetterCustom(MyStaticSanitizerCallback)]
public partial string MySecretString { get; set; }
Breaking change?

No

Alternatives

The team can find a better way and/or names to do such, right now I don't see another alternative than using atributes.

Additional context
  • Also implement other sanitizers useful to other uses and types
  • If doing for setter we can also do for getter side?
Help us help you

Yes, I'd like to be assigned to work on this item

主要语言
C#
星标
3.8k
派生
401
PR 合并指标
30 天内没有已合并 PR

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

CommunityToolkit/dotnet 的其他 Issue

查看 CommunityToolkit/dotnet 的全部 Issue

相似的 Issue

更多 C# Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。