可以构建.NET BinaryReader/BinaryWriter
类,并指定用于Encoding
相关操作的String
。
我使用扩展方法实现自定义字符串格式,但是在实例化Encoding
时它们会尊重指定的BinaryReader/Writer
。
似乎没有办法从读取器/写入器检索编码,即使从类继承也没有。我只能通过重新创建所有构造函数来继承它们来拦截传递的编码。我查看了.NET source code,它只用于实例化一个Decoder类(如果是BinaryReader
),但我也无法访问那个。
我在这些课程中是否会遇到缺点?我可以用反射入侵它们吗?
答案 0 :(得分:5)
查看source code for 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
变量之外,几乎可以肯定有更好的方法来解决您的问题。即使你这样做了,也可能没有像你在评论中提到的那样得到编码。但是,如果您仍想要这样做,请参阅this StackOverflow answer on how to access private members with reflection。
答案 1 :(得分:3)
如果在你的场景中对构造函数中的编码进行子类化和拦截甚至是远程可行的,我更喜欢它而不是可能不稳定的反射黑客。
但是,如果你必须出于某种原因去反射路线,这里有一些我在the BinaryReader source code you referenced找到的指示:
Decoder
类本身显然没有引用Encoding
,但是:Decoder
实例是通过调用encoding.GetDecoder()
(第65行)DefaultDecoder
m_encoding
Encoding