10

可以通过指定用于 -相关操作的 .NETBinaryReader/BinaryWriter类来构造。EncodingString

我正在使用扩展方法实现自定义字符串格式,但Encoding在实例化BinaryReader/Writer.

似乎没有办法从读取器/写入器检索编码,即使从他们的类继承也是如此。我只能从他们那里继承来通过重新创建他们的所有构造函数来拦截传递的编码。我查看了.NET 源代码,它仅用于实例化解码器类(在 .NET 的情况下BinaryReader),但我也无法访问该类。

我会输给这些课程的缺点吗?我可以通过反射侵入它们吗?

4

2 回答 2

5

查看 BinaryReader的源代码,我看到构造函数定义如下:

    public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
        if (input==null) {
            throw new ArgumentNullException("input");
        }
        if (encoding==null) {
            throw new ArgumentNullException("encoding");
        }
        if (!input.CanRead)
            throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
        Contract.EndContractBlock();
        m_stream = input;
        m_decoder = encoding.GetDecoder();
        m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
        int minBufferSize = encoding.GetMaxByteCount(1);  // max bytes per one char
        if (minBufferSize < 16) 
            minBufferSize = 16;
        m_buffer = new byte[minBufferSize];
        // m_charBuffer and m_charBytes will be left null.

        // For Encodings that always use 2 bytes per char (or more), 
        // special case them here to make Read() & Peek() faster.
        m_2BytesPerChar = encoding is UnicodeEncoding;
        // check if BinaryReader is based on MemoryStream, and keep this for it's life
        // we cannot use "as" operator, since derived classes are not allowed
        m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
        m_leaveOpen = leaveOpen;

        Contract.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
    }

所以看起来编码本身实际上并没有保留在任何地方。该类仅存储从编码派生的解码器。m_decoder在类中定义如下:

    private Decoder  m_decoder;

您无法访问私有变量。在类的其余部分中搜索该变量表明它在内部的几个地方使用,但从未返回,所以我认为你不能在派生类的任何地方访问它而不做某种疯狂的反射/反汇编事情. 必须将其定义protected为您才能访问它。对不起。

编辑:

几乎可以肯定有比使用反射访问私有m_decoder变量更好的方法来解决您的问题。即使您这样做了,它也可能无法为您提供编码,正如您在评论中指出的那样。但是,如果您仍然想这样做,请参阅有关如何使用反射访问私有成员的 StackOverflow 答案

于 2015-04-03T16:41:29.923 回答
3

如果在您的场景中子类化和拦截构造函数中的编码甚至是远程可行的,我更喜欢它而不是潜在的不稳定反射黑客。

但是,如果您出于某种原因必须走反射路线,以下是我从您引用的 BinaryReader 源代码中找到的一些指针:

于 2015-04-03T16:59:41.847 回答