SqlXml不负责处理MemoryStream

本文关键字:处理 MemoryStream SqlXml | 更新日期: 2023-09-27 18:06:19

我今天正在看代码审查,其中有人试图通过将其包装在using块中来处理MemoryStream。在这种情况下,它被传递到一个SqlXml实例中,我不确定它对它做了什么,所以我快速查看了反编译的源代码。下面是示例代码:

using(MemoryStream ms = new MemoryStream(data)) {
   var param = new SqlXml(ms);
   var parameter = new SqlParameter("@Xml", System.Data.SqlDbType.Xml) { Value = param };
   command.Parameters.Add(parameter);
}
return command;

这是反编译的源代码:

public SqlXml(Stream value)
{
    if (value == null)
    {
        this.SetNull();
    }
    else
    {
        this.firstCreateReader = true;
        this.m_fNotNull = true;
        this.m_stream = value;
    }
}

现在最佳实践说SqlXml现在应该负责处理这个流。但不幸的是,它没有实现IDisposable

最重要的是,我不知道包含它的SqlCommand何时被消耗,SqlXml何时被密封,所以我可以实际地扩展它。

谁能建议一个好的方法来处理这个问题?我打算在微软的某个地方记录一个错误,因为这不是一件很好的事情,必须要解决。

我目前最好的建议是使用接受XmlReader的构造函数,因为它至少复制了内容,所以阅读器可以被处理-然而在内部,它只是创建了一个MemoryStream,也从不清除它。

SqlXml不负责处理MemoryStream

在实现IDisposable时要记住的一件重要的事情是不要处理不"拥有"的IDisposable实例。(您的类没有专门创建的那些)。所以TL;DR, SqlXml实现IDisposable不是一个好主意,因为它没有创建底层的Stream

SqlXml当然不应该释放内存流:它是由它的(未知的)调用者传递的,调用者很可能会进一步使用它。SqlXml不拥有流,如果它确实处理它,它可能会中断调用者,因此它应该在将它放在需要的地方后单独离开。