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

C#中如何扩展StringReader实现支持多步预读的Peek方法?

C# StringReader 多字符预读Peek扩展实现

实现代码

using System;
using System.IO;
using System.Reflection;

public static class StringReaderExtensions
{
    // 缓存私有字段反射信息,仅首次调用执行反射查询,大幅提升后续调用性能
    private static readonly FieldInfo _underlyingStringField = typeof(StringReader).GetField("_s", BindingFlags.Instance | BindingFlags.NonPublic);
    private static readonly FieldInfo _currentPositionField = typeof(StringReader).GetField("_pos", BindingFlags.Instance | BindingFlags.NonPublic);

    /// <summary>
    /// 预读指定数量的字符,不移动读取指针
    /// </summary>
    /// <param name="reader">目标StringReader实例</param>
    /// <param name="count">预读字符数</param>
    /// <returns>预读到的字符数组,长度不超过剩余字符数</returns>
    /// <exception cref="ArgumentNullException">reader为null时抛出</exception>
    /// <exception cref="ArgumentOutOfRangeException">预读步数小于0时抛出</exception>
    public static char[] Peek(this StringReader reader, int count)
    {
        if (reader == null)
            throw new ArgumentNullException(nameof(reader));
        if (count < 0)
            throw new ArgumentOutOfRangeException(nameof(count), "预读步数不能小于0");
        if (count == 0)
            return Array.Empty<char>();

        // 直接读取StringReader内部存储的原始字符串和当前读取位置,不修改原有状态
        string originalString = (string)_underlyingStringField.GetValue(reader);
        int currentPos = (int)_currentPositionField.GetValue(reader);

        // 计算实际可取的字符数,避免越界
        int availableCount = originalString.Length - currentPos;
        int actualTakeCount = Math.Min(count, availableCount);

        return actualTakeCount <= 0 ? Array.Empty<char>() : originalString.Substring(currentPos, actualTakeCount).ToCharArray();
    }
}

使用示例

var input = "Sample";
var reader = new StringReader(input);

// 预读3个字符
var result1 = reader.Peek(3);
// 结果:['S','a','m']

// 预读超过剩余长度的字符
var result2 = reader.Peek(10);
// 结果:['S','a','m', 'p','l','e']

// 验证读取指针未移动
var firstChar = reader.Read();
// 输出为'S',指针仅在调用Read后才移动

注意事项

  • 用到的_s、_pos私有字段是.NET Framework、.NET Core、.NET 5+全版本通用的StringReader内置字段,兼容性稳定
  • 完全符合需求要求:不移动读取指针、预读长度不足时返回所有剩余字符
  • 静态缓存反射信息的设计可满足词法分析器高频调用的性能要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:24:01