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

如何实现可表示int、null或自身数组的C#类?

设计问题:实现支持int/null/自身数组的类

需求说明

创建MyIntOrArray类,其实例需支持三种形态:int值、null、该类的数组。调用打印方法时需满足:

  • 若为int值,打印对应数字
  • 若为null,无任何操作
  • 若为数组,遍历并打印内部元素

补充要求:对于结构[[1,2,3], null, 4, 5, [6,null,7]](所有元素包括主数组均为MyIntOrArray类型),调用打印方法7次需依次输出"1""2""3""4""5""6""7"。核心关注类的实现结构,而非打印功能细节。

尝试实现代码

public class MyIntOrArray
{
    public int? Value { get; set; }
    public MyIntOrArray[] Values { get; set; }
    private bool AmIArray { get; set; }
    private int InnerIndex { get; set; }

    public MyIntOrArray(int? value)
    {
        Value = value;
        AmIArray = false;
    }

    public MyIntOrArray(int size, bool isArray)
    {
        Values = new MyIntOrArray[size];
        AmIArray = true;
    }

    public bool Print()
    {
        if(AmIArray)
        {
            if (InnerIndex < Values.Length)
            {
                if (Values[InnerIndex].Print())
                    InnerIndex += 1;

                return InnerIndex >= Values.Length ? true : false;
            }                
        }
        else if(Value != null) 
        {
            Console.WriteLine(Value.ToString());                
        }

        return true;
    }
}

优雅实现方案

方案一:基于继承与多态的实现

通过抽象基类+子类的方式,明确区分三种形态,符合单一职责原则:

// 抽象基类,定义统一行为
public abstract class MyIntOrArray
{
    public abstract bool Print();
}

// 表示int值的子类
public class MyInt : MyIntOrArray
{
    public int Value { get; }

    public MyInt(int value) => Value = value;

    public override bool Print()
    {
        Console.WriteLine(Value.ToString());
        return true;
    }
}

// 表示null的单例子类
public class MyNull : MyIntOrArray
{
    public static readonly MyNull Instance = new MyNull();
    private MyNull() { }

    public override bool Print() => true;
}

// 表示数组的子类
public class MyIntArray : MyIntOrArray
{
    private readonly MyIntOrArray[] _elements;
    private int _currentIndex = 0;

    public MyIntArray(params MyIntOrArray[] elements) => _elements = elements;

    public override bool Print()
    {
        if (_currentIndex >= _elements.Length)
            return true;

        if (_elements[_currentIndex].Print())
            _currentIndex++;

        return _currentIndex >= _elements.Length;
    }
}

优势

  • 类型职责清晰:每个子类仅对应一种形态,避免无效状态组合
  • 多态特性消除了原代码中的AmIArray标记字段,结构更简洁
  • 实例创建直观,比如构建需求示例:
var example = new MyIntArray(
    new MyIntArray(new MyInt(1), new MyInt(2), new MyInt(3)),
    MyNull.Instance,
    new MyInt(4),
    new MyInt(5),
    new MyIntArray(new MyInt(6), MyNull.Instance, new MyInt(7))
);

方案二:单类+静态工厂的实现

如果不想引入继承体系,可通过私有构造+静态工厂方法限制实例形态,避免无效状态:

public class MyIntOrArray
{
    private readonly int? _intValue;
    private readonly MyIntOrArray[] _arrayValue;
    private readonly bool _isNull;
    private int _arrayIndex = 0;

    // 私有构造,仅允许通过静态方法创建实例
    private MyIntOrArray(int? intValue, MyIntOrArray[] arrayValue, bool isNull)
    {
        _intValue = intValue;
        _arrayValue = arrayValue;
        _isNull = isNull;
    }

    // 创建int类型实例
    public static MyIntOrArray FromInt(int value) => new MyIntOrArray(value, null, false);
    // 创建null类型实例
    public static MyIntOrArray FromNull() => new MyIntOrArray(null, null, true);
    // 创建数组类型实例
    public static MyIntOrArray FromArray(params MyIntOrArray[] elements) => new MyIntOrArray(null, elements, false);

    public bool Print()
    {
        if (_isNull)
            return true;

        if (_intValue.HasValue)
        {
            Console.WriteLine(_intValue.Value.ToString());
            return true;
        }

        if (_arrayIndex >= _arrayValue.Length)
            return true;

        if (_arrayValue[_arrayIndex].Print())
            _arrayIndex++;

        return _arrayIndex >= _arrayValue.Length;
    }
}

优势

  • 用静态工厂方法确保实例只能是三种合法形态之一,避免原代码中Value和Values同时赋值的无效状态
  • 结构紧凑,无需额外子类
  • 调用方式直观:
var example = MyIntOrArray.FromArray(
    MyIntOrArray.FromArray(MyIntOrArray.FromInt(1), MyIntOrArray.FromInt(2), MyIntOrArray.FromInt(3)),
    MyIntOrArray.FromNull(),
    MyIntOrArray.FromInt(4),
    MyIntOrArray.FromInt(5),
    MyIntOrArray.FromArray(MyIntOrArray.FromInt(6), MyIntOrArray.FromNull(), MyIntOrArray.FromInt(7))
);

原实现的问题点

  1. 状态冗余:Value和Values字段同时存在,可能出现既设置int值又设置数组的无效状态
  2. 实例不可复用:InnerIndex作为实例私有字段,导致数组实例多次调用Print时会从上次的位置继续,无法重置
  3. 标记式设计:AmIArray字段属于“标记式”判断,不如多态或明确状态区分的设计优雅

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:04:50