Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回用内存流初始化的SqlXml_C#_Xml - Fatal编程技术网

C# 返回用内存流初始化的SqlXml

C# 返回用内存流初始化的SqlXml,c#,xml,C#,Xml,我试图从一个使用方法本地内存流初始化它的方法返回一个SqlXml对象。即 using (Stream memoryStream = new MemoryStream()) { using (XmlWriter writer = XmlWriter.Create(memoryStream, new XmlWriterSettings { OmitXmlDeclaration = true })) { s

我试图从一个使用方法本地内存流初始化它的方法返回一个SqlXml对象。即

using (Stream memoryStream = new MemoryStream())
        {
            using (XmlWriter writer = XmlWriter.Create(memoryStream, new XmlWriterSettings { OmitXmlDeclaration = true }))
            {
                serializer.Serialize(writer, myList.ToArray(), ns);
                return new SqlXml(memoryStream);
            }
        }
现在,调用它并尝试访问其字段的方法失败,出现
对象处理异常

我快速瞥了一眼,发现它只是保留了对描述行为的流的引用

public SqlXml(Stream value) {
            // whoever pass in the stream is responsible for closing it
            // similar to SqlBytes implementation
            if (value == null) {
                SetNull();
            }
            else  {
                firstCreateReader = true;
                m_fNotNull = true;
                m_stream = value;
            }
我真的很想避免调用方必须通过流并对其生命周期负责。是否有其他方法可以完全初始化SqlXml对象并安全地处理内存流

编辑:

一种可能的解决方案是使用temp SqlXml变量,然后通过create reader构造函数使用它初始化返回对象:

using (Stream memoryStream = new MemoryStream())
        {
            using (XmlWriter writer = XmlWriter.Create(memoryStream, new XmlWriterSettings { OmitXmlDeclaration = true }))
            {
                serializer.Serialize(writer, myList.ToArray(), ns);
                SqlXml s = new SqlXml(memoryStream);
                return new SqlXml(s.CreateReader());
            }
        }
但这在我看来仍然有点笨拙。

当块退出时,该语句将在流上调用dispose。将MemoryStream从使用块中取出,在返回之前不会进行处理

class Program
{
    static void Main(string[] args)
    {
        var s = GetData();
        var r = s.CreateReader();
        while (r.Read())
        {
            if (r.NodeType == XmlNodeType.Element)
            {
                System.Console.WriteLine(r.Name);
            }
        }
        r.Close();
    }

    private static SqlXml GetData()
    {
        var mem = new MemoryStream();
        //TODO: Deserialize or query data.
        return new SqlXml(mem);
    }
}

如果调用方请求流,他们应该负责处理流。流生成代码不应负责处理它,因为它无法知道何时不再需要流。也许您可以创建一个工厂或使用一个IOC容器来控制流的创建,然后处理流。是的,但流在内部用于序列化。调用方不应该真正关心方法如何在内部构造xml(在本例中是通过流)。一旦开始处理非托管资源,托管内存世界中的事情就变得不那么简单了。也许您可以从这个答案中获得一些想法,讨论IDisposable以及谁负责处理传递的IDisposable实现者: