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

C#同名字符串扩展方法能否基于语法自动路由至对应实现?

实现方案说明

.NET 本身没有内置类似 [RequiresSyntax(...)] 的属性来自动路由同名扩展方法,但可以通过两种方式实现你想要的逻辑分离+自动匹配调用的需求:


方案一:自定义属性+反射路由(接近你设想的属性标记方式)

通过自定义属性标记各扩展方法对应的正则规则,再写一个统一的入口方法,在运行时通过反射匹配规则并调用对应方法。

1. 定义标记属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RequiresSyntaxAttribute : Attribute
{
    public string RegexPattern { get; }

    public RequiresSyntaxAttribute(string regexPattern)
    {
        RegexPattern = regexPattern;
    }
}

2. 编写分离的逻辑类

分别在不同静态类中实现对应格式的比较逻辑:

public static class VersionsExtensions
{
    [RequiresSyntax(@"^([A-Z]\d{2}!\[A-Z]{2}\d|[A-Z]{3})$")]
    public static bool IsHigher(this string source, string target)
    {
        // 版本字符串的具体比较逻辑,示例为字典序,可按需修改
        return string.Compare(source, target, StringComparison.Ordinal) > 0;
    }
}

public static class IssuesExtensions
{
    [RequiresSyntax(@"^\d{3}$")]
    public static bool IsHigher(this string source, string target)
    {
        // 工单编号的具体比较逻辑
        return int.Parse(source) > int.Parse(target);
    }
}

3. 实现路由入口方法

写一个统一的扩展方法作为入口,负责匹配规则并调用对应逻辑:

public static class StringSyntaxRouter
{
    // 缓存规则与方法映射,避免重复反射扫描
    private static readonly List<(Regex Regex, MethodInfo Method)> _syntaxMethods;

    static StringSyntaxRouter()
    {
        // 扫描所有标记了RequiresSyntaxAttribute的静态方法
        _syntaxMethods = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(a => a.GetTypes())
            .Where(t => t.IsStatic)
            .SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Static))
            .Where(m => m.GetCustomAttribute<RequiresSyntaxAttribute>() != null)
            .Select(m => 
            {
                var attr = m.GetCustomAttribute<RequiresSyntaxAttribute>();
                return (Regex: new Regex(attr.RegexPattern, RegexOptions.Compiled), Method: m);
            })
            .ToList();
    }

    public static bool IsHigher(this string source, string target)
    {
        if (source == null || target == null)
            throw new ArgumentNullException();

        // 匹配source对应的规则方法
        var matched = _syntaxMethods.FirstOrDefault(s => s.Regex.IsMatch(source));
        if (matched.Method == null)
            throw new InvalidOperationException("未找到匹配的语法规则方法");

        // 验证target格式与source一致(可根据需求调整是否需要此校验)
        if (!matched.Regex.IsMatch(target))
            throw new ArgumentException("目标字符串格式与源字符串不匹配");

        // 调用对应逻辑方法
        return (bool)matched.Method.Invoke(null, new object[] { source, target });
    }

    // 同理实现IsLower方法
    public static bool IsLower(this string source, string target)
    {
        var isHigher = source.IsHigher(target);
        return !isHigher && !string.Equals(source, target);
    }
}

方案二:模式匹配+轻量路由(性能更优)

如果不想用反射,可在入口方法中通过预编译的正则做格式判断,直接调用对应静态类的逻辑,既保持逻辑分离,又避免反射开销:

public static class StringComparisonExtensions
{
    // 预编译正则,提升匹配性能
    private static readonly Regex _versionRegex = new Regex(@"^([A-Z]\d{2}!\[A-Z]{2}\d|[A-Z]{3})$", RegexOptions.Compiled);
    private static readonly Regex _issueRegex = new Regex(@"^\d{3}$", RegexOptions.Compiled);

    public static bool IsHigher(this string source, string target)
    {
        if (_versionRegex.IsMatch(source) && _versionRegex.IsMatch(target))
            return VersionsExtensions.IsHigher(source, target);
        
        if (_issueRegex.IsMatch(source) && _issueRegex.IsMatch(target))
            return IssuesExtensions.IsHigher(source, target);
        
        throw new InvalidOperationException("不支持的字符串格式");
    }

    public static bool IsLower(this string source, string target)
    {
        if (_versionRegex.IsMatch(source) && _versionRegex.IsMatch(target))
            return !VersionsExtensions.IsHigher(source, target) && !string.Equals(source, target);
        
        if (_issueRegex.IsMatch(source) && _issueRegex.IsMatch(target))
            return !IssuesExtensions.IsHigher(source, target) && !string.Equals(source, target);
        
        throw new InvalidOperationException("不支持的字符串格式");
    }
}

调用方式

两种方案都支持你想要的调用形式:

// 调用版本字符串比较
"A00".IsLower("B00");
// 调用工单编号比较
"001".IsLower("002");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:30:14