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

C#:能否通过只读包装器调用List的LastIndexOf等成员方法?

解决方法

下面提供几种实用的方案,你可以根据实际场景选择:

方案1:给IReadOnlyList<T>编写LastIndexOf扩展方法

这是最通用的方案,不管传入的是List的只读包装还是其他实现IReadOnlyList<T>的类型,都能正常工作:

public static class ReadOnlyListExtensions
{
    public static int LastIndexOf<T>(this IReadOnlyList<T> list, T value)
    {
        // 从列表末尾向前遍历,找到第一个匹配的元素索引
        for (int i = list.Count - 1; i >= 0; i--)
        {
            if (EqualityComparer<T>.Default.Equals(list[i], value))
            {
                return i;
            }
        }
        return -1;
    }
}

// 修改后的Bar函数
int Bar(IReadOnlyList<int> list, int value)
{
    int i1 = list.IndexOf(value);
    int i2 = list.LastIndexOf(value); // 现在可以调用扩展方法
    return i2 - i1;
}

// 调用示例
List<int> list = new List<int> { 1, 2, 3, 2, 1 };
Console.WriteLine(Bar(list.AsReadOnly(), 1)); // 输出4

方案2:针对ReadOnlyCollection<T>做适配

因为list.AsReadOnly()返回的是ReadOnlyCollection<T>,它内部持有原List的引用,可以通过Items属性直接调用原List的LastIndexOf方法:

int Bar(IReadOnlyList<int> list, int value)
{
    int i1 = list.IndexOf(value);
    int i2;
    
    // 优先处理ReadOnlyCollection的情况
    if (list is ReadOnlyCollection<int> readOnlyCol)
    {
        i2 = readOnlyCol.Items.LastIndexOf(value);
    }
    // 兼容直接传入List的场景
    else if (list is List<int> concreteList)
    {
        i2 = concreteList.LastIndexOf(value);
    }
    // 其他情况回退到自定义遍历
    else
    {
        i2 = list.LastIndexOf(value); // 复用方案1的扩展方法
    }
    
    return i2 - i1;
}

这个方案在处理List的只读包装时性能和原方法完全一致,但耦合了具体类型,适合你主要使用List的场景。

方案3:用LINQ快速实现(适合小数据量场景)

如果列表数据量不大,用LINQ的Reverse配合IndexOf可以快速实现,缺点是会生成新列表,大数据量下性能一般:

int Bar(IReadOnlyList<int> list, int value)
{
    int i1 = list.IndexOf(value);
    // 转换反向列表的索引为原列表的索引
    int reversedIndex = list.Reverse().ToList().IndexOf(value);
    int i2 = reversedIndex == -1 ? -1 : list.Count - 1 - reversedIndex;
    
    return i2 - i1;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:05:27