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

如何避免在集合所用接口的方法中使用object类型参数?

避免object类型,提升类型安全并消除装箱/拆箱的解决方案

当前代码通过object存储检查结果值,存在类型转换风险、编译时无法校验类型,以及值类型装箱/拆箱的性能损耗问题。要在保持集合存储能力的前提下解决这些问题,泛型接口+访问者模式是非常合适的方案,既能满足统一集合存储,又能完全消除object的使用。

重构后的代码实现

1. 定义访问者与验证器接口

先通过访问者模式的接口,实现不同类型结果的类型安全处理:

// 非泛型访问者基接口,用于集合中统一调用
public interface IResultVisitor
{
    void Visit(StringResult result);
    void Visit(DoubleResult result);
    void Visit(EnumResult<MyEnum> result);
    // 新增类型时扩展对应的Visit方法即可
}

// 泛型验证器接口,绑定具体类型的验证逻辑
public interface IResultValidator<T>
{
    bool Validate(T value);
}

2. 定义结果接口与实现类

用非泛型接口作为集合存储的统一类型,泛型接口实现强类型值存储:

// 非泛型基接口,用于存入集合
public interface IServiceCheckResult
{
    void Accept(IResultVisitor visitor);
}

// 泛型结果接口,强类型管理值与验证器
public interface IServiceCheckResult<T> : IServiceCheckResult
{
    T Value { get; set; }
    IResultValidator<T> Validator { get; }
}

// 字符串结果实现
public class StringResult : IServiceCheckResult<string>
{
    public string Value { get; set; } = string.Empty;
    public IResultValidator<string> Validator { get; }

    public StringResult(IResultValidator<string> validator)
    {
        Validator = validator;
    }

    public void Accept(IResultVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// 双精度浮点数结果实现
public class DoubleResult : IServiceCheckResult<double>
{
    public double Value { get; set; }
    public IResultValidator<double> Validator { get; }

    public DoubleResult(IResultValidator<double> validator)
    {
        Validator = validator;
    }

    public void Accept(IResultVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// 泛型枚举结果实现
public class EnumResult<TEnum> : IServiceCheckResult<TEnum> where TEnum : Enum
{
    public TEnum Value { get; set; } = default!;
    public IResultValidator<TEnum> Validator { get; }

    public EnumResult(IResultValidator<TEnum> validator)
    {
        Validator = validator;
    }

    public void Accept(IResultVisitor visitor)
    {
        visitor.Visit(this);
    }
}

3. 具体验证器实现

每个验证器绑定对应类型,无需强制转换:

public class StringEmptyValidator : IResultValidator<string>
{
    public bool Validate(string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

public class DoublePositiveValidator : IResultValidator<double>
{
    public bool Validate(double value)
    {
        return value > 0;
    }
}

public class EnumValidValidator : IResultValidator<MyEnum>
{
    public bool Validate(MyEnum value)
    {
        return Enum.IsDefined(typeof(MyEnum), value);
    }
}

4. 验证执行的访问者

实现访问者来统一处理所有类型的验证逻辑:

public class ValidationVisitor : IResultVisitor
{
    // 存储所有验证结果
    public List<bool> ValidationResults { get; } = new();

    public void Visit(StringResult result)
    {
        ValidationResults.Add(result.Validator.Validate(result.Value));
    }

    public void Visit(DoubleResult result)
    {
        ValidationResults.Add(result.Validator.Validate(result.Value));
    }

    public void Visit(EnumResult<MyEnum> result)
    {
        ValidationResults.Add(result.Validator.Validate(result.Value));
    }
}

5. 优化后的ServiceCheck与使用示例

可以给ServiceCheck添加泛型方法,避免设置值时的强制转换:

public class ServiceCheck
{
    private readonly List<IServiceCheckResult> _results = new();

    public IReadOnlyList<IServiceCheckResult> Results => _results.AsReadOnly();

    public void AddResult<T>(IServiceCheckResult<T> result)
    {
        _results.Add(result);
    }

    public IServiceCheckResult<T>? GetResult<T>(int index)
    {
        return _results[index] as IServiceCheckResult<T>;
    }
}

// 使用示例
var serviceCheck = new ServiceCheck();
serviceCheck.AddResult(new DoubleResult(new DoublePositiveValidator()));
serviceCheck.AddResult(new StringResult(new StringEmptyValidator()));
serviceCheck.AddResult(new EnumResult<MyEnum>(new EnumValidValidator()));

// 强类型设置值,无装箱/拆箱,编译时校验类型
serviceCheck.GetResult<double>(0)!.Value = 1.0;
serviceCheck.GetResult<string>(1)!.Value = "This is a test";
serviceCheck.GetResult<MyEnum>(2)!.Value = MyEnum.None;

// 执行验证
var validationVisitor = new ValidationVisitor();
foreach (var result in serviceCheck.Results)
{
    result.Accept(validationVisitor);
}

// 输出验证结果
foreach (var isValid in validationVisitor.ValidationResults)
{
    Console.WriteLine(isValid);
}

方案优势

  • 完全类型安全:所有值都是强类型存储,编译时就能发现类型错误,避免运行时强制转换异常
  • 消除装箱/拆箱:值类型(如double、枚举)直接存储,没有object带来的装箱损耗
  • 扩展性良好:新增结果类型时,只需扩展访问者的Visit方法、新增对应结果类和验证器,符合开闭原则
  • 职责清晰:结果类负责存值,验证器负责校验逻辑,访问者负责统一处理,代码结构更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:57:22