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

C#如何匹配不同类的泛型类型并校验能力是否满足对应需求

前置修复说明

你现有代码存在两个需要先调整的小问题:

  1. SetCapability<T>未实现ICapability接口,无法存入List<ICapability>集合,需要先补上继承关系
  2. 区间比较需要泛型参数T支持大小比较,建议给RangeCapability<T>加上IComparable<T>的泛型约束

方案1:校验逻辑下沉到能力类(推荐,符合开闭原则)

直接在ICapability接口中定义校验契约,每个具体能力类自行实现类型匹配、值校验逻辑,上层无需关心泛型匹配的细节。

public interface ICapability
{
    public string Name { get; }
    // 新增校验方法契约
    bool IsMatch(IRequirement requirement);
}

// Range能力实现
public class RangeCapability<T> : ICapability where T : IComparable<T>
{
    public string Name { get; set; }
    public T Min { get; set; }
    public T Max { get; set; }

    public bool IsMatch(IRequirement requirement)
    {
        // 先匹配泛型需求类型
        if (requirement is not Requirement<T> req)
            return false;
        // 校验区间
        return req.Value.CompareTo(Min) >= 0 && req.Value.CompareTo(Max) <= 0;
    }
}

// Set能力实现,补上ICapability继承
public class SetCapability<T> : ICapability
{
    public string Name { get; set; }
    public HashSet<T> Set { get; set; }

    public bool IsMatch(IRequirement requirement)
    {
        if (requirement is not Requirement<T> req)
            return false;
        return Set.Contains(req.Value);
    }
}

Entity的校验逻辑可以简化为:

public class Entity
{
    public List<ICapability> Capabilities { get; set; } = new();

    public bool IsSatisfying(List<IRequirement> requirements)
    {
        foreach (var requirement in requirements)
        {
            var capability = Capabilities.FirstOrDefault(x => x.Name == requirement.Name);
            // 找不到对应能力/校验不通过直接返回不满足
            if (capability == null || !capability.IsMatch(requirement))
                return false;
        }
        return true;
    }
}

该方案后续新增能力类型只要实现IsMatch方法即可,上层校验逻辑完全不需要修改,扩展性更强。


方案2:不改现有接口定义,用动态分派实现

如果你不能修改ICapability和能力类的原有定义,可以用运行时动态重载匹配来处理泛型类型的校验:

public class Entity
{
    public List<ICapability> Capabilities { get; set; } = new();

    public bool IsSatisfying(List<IRequirement> requirements)
    {
        foreach (var requirement in requirements)
        {
            var capability = Capabilities.FirstOrDefault(x => x.Name == requirement.Name);
            if (capability == null)
                return false;
            // 动态分派,运行时自动匹配对应泛型类型的校验重载
            if (!CheckMatch(capability as dynamic, requirement as dynamic))
                return false;
        }
        return true;
    }

    // 泛型Range校验重载
    private bool CheckMatch<T>(RangeCapability<T> cap, Requirement<T> req) where T : IComparable<T>
    {
        return req.Value.CompareTo(cap.Min) >= 0 && req.Value.CompareTo(cap.Max) <= 0;
    }

    // 泛型Set校验重载
    private bool CheckMatch<T>(SetCapability<T> cap, Requirement<T> req)
    {
        return cap.Set.Contains(req.Value);
    }

    // 类型不匹配时的兜底重载
    private bool CheckMatch(object cap, object req)
    {
        // 泛型类型不匹配,返回校验失败
        return false;
    }
}

该方案依赖运行时动态类型解析,性能比方案1略低,适合小范围使用的场景。


补充说明

两种方案默认都是严格匹配泛型类型,比如RangeCapability<int>和Requirement<long>就算数值范围符合也会判定为类型不匹配,如果你需要支持兼容数值类型转换,可以在校验逻辑里额外加类型转换处理。找不到同名能力时的处理逻辑也可以按业务需求调整,比如部分场景不需要所有需求都有对应能力,可以跳过校验返回true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:36:02