私は、XML文書を含む文字列とXSDであるストリームの配列を受け入れるC#で書いているメソッドを持っています。文字列の文書は、のXSDに対して検証されていますC#:ストリームを呼び出されたメソッドで閉じたり破棄したりする必要がありますか?
private static XmlValidationResult ValidateDocumentInternal(string document, params Stream[] xsdStreams)
{
XmlReaderSettings settings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema
};
foreach (var xsdStream in xsdStreams)
{
using (xsdStream)
{
XmlReader xmlReader = XmlReader.Create(xsdStream);
try
{
settings.Schemas.Add(null, xmlReader);
}
finally
{
xmlReader.Close();
}
}
}
var validationErrors = new List<string>();
settings.ValidationEventHandler += (object sender, System.Xml.Schema.ValidationEventArgs e) =>
{
validationErrors.Add($"({e.Exception.LineNumber}): {e.Message}");
};
using (var stream = document.ToStream())
{
var reader = XmlReader.Create(stream, settings);
while (reader.Read())
{
}
}
return new XmlValidationResult
{
Success = validationErrors.Count == 0,
ValidationErrors = validationErrors
};
}
私の質問は、この方法は、XSDの流れを処分しなければならない場合、またはそれは、呼び出し側の責任ですべきですか?
var document = GetDocument();
Stream xsd = GetXSD();
var validationResult = ValidateDocumentInternal(document, xsd);
またはそれが(ValidateDocumentInternal
にストリームを廃棄しない)ようにする必要があります:
var document = GetDocument();
using (Stream xsd = GetXSD()) {
var validationResult = = ValidateDocumentInternal(document, xsd);
}
または文書とXSDに渡すと期待しValidateDocumentInternal
をXSDストリームを配置するには、次のコードを想像してみて代わりに、私はちょうどbool
処分するかどうかを言って渡す必要がありますか?
味の問題かもしれませんが個人的には、私はあなたの第2のオプション( '使用する')を好むでしょう。 – Heinzi
私は、作成されたスコープ内のストリームを常にクローズしています。そのため、メソッド実装のブラックボックスでストリームを作成するのではなく、呼び出し元の責任にしています。しかし、一部の.net APIは、廃棄の所有権を取得するためのフラグを提供しています...省略可能な省略可能なパラメータとしてfalseを指定することもできます。 – spender
私は通常、「ストリームを作成するコードはそれを閉じる責任があります」というルールを採用しています。これが不適切な場合があります。たとえば、ストリームが非常に長い間開いている場合などです。あなたが何をするにしても、発信者がストリームで行うことを文書化することが重要です。これは、呼び出し元が提供されたオブジェクトの状態を変更するすべてのパラメータに当てはまりますが、ストリームを読む誰かがその状態を変更していることをよく見落とします。 –