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

C#泛型场景下如何传入整数值而非类型以消除FixedArray冗余代码

方案1:C# 11+ 数字泛型参数(最优解)

如果你可以升级到C# 11/.NET 7及以上版本,直接用语言内置的数值类型作为泛型参数特性,完全不需要自定义任何VM类,零冗余代码:

sealed class FixedArray<T, Length> : IStructuralComparable where T : struct where Length : INumber<int>
{
    public T[] array { get; init; }
    public FixedArray()
    {
        // Length是编译期常量,JIT会直接优化成固定长度数组分配,无任何运行时开销
        array = new T[Length];
    }

    public int CompareTo(object? other, IComparer comparer) => ((IStructuralComparable)array).CompareTo(other, comparer);
}

使用的时候直接传长度值就行,比你原来的写法更简洁:

var int2 = new FixedArray<int, 2>(); // 等价你原来的FixedArray<int, VM2>
var double3 = new FixedArray<double, 3>();
var ushort6 = new FixedArray<ushort, 6>();

方案2:低版本C# 用源生成器自动生成VM类

如果要兼容旧版本框架,不需要手动写每个VMxxx的实现,写一个简单的C#源生成器,扫描你代码里用到的所有FixedArray<T, VMxxx>的长度,或者预定义你需要的长度列表(就是你补充的1、2、3...24这些值),自动生成所有实现了IVM接口的结构体代码,完全避免手动写样板代码。
生成的代码可以直接标记为internal,对你的业务代码透明,你只需要维护一份长度列表就行,新增长度只要改列表,不需要手动加类。

方案3:范围值的处理

针对你补充的1-2、1-3这类范围类型的需求,可以单独加一套泛型参数逻辑:

// 范围接口定义
interface IVMRange
{
    int Min { get; }
    int Max { get; }
}

// 固定长度和范围可以二选一作为泛型参数,用约束区分逻辑
sealed class FixedArray<T, TLength> : IStructuralComparable 
    where T : struct 
    where TLength : new()
{
    public T[] array { get; init; }
    public FixedArray()
    {
        var lenParam = new TLength();
        if (lenParam is IVM fixedLen)
        {
            array = new T[fixedLen.Value];
        }
        else if (lenParam is IVMRange range)
        {
            // 你自己的范围场景初始化逻辑
            array = new T[range.Max];
        }
    }
    // 其他方法省略
}

同样范围的VM类也可以用源生成器批量生成,不需要手动编写。

原有实现的优化提示

你现在的实现其实已经可以满足需求,所有VM类的无参构造和Value属性都是编译期常量,JIT在运行时会完全优化掉new VM().Value的调用,直接替换成对应常量,不会有额外的性能开销,唯一的冗余就是VM类的手写代码,用源生成器就能解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:45:01