У меня есть метод, который я пишу на C#, который принимает строку, которая содержит XML-документ, и массив потоков, которые являются XSD. Строка документа сверяются с XSDs: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 потоков или, что должно быть обязанностью вызывающей? Представьте себе следующий код, который проходит в документе и XSD и ожидает ValidateDocumentInternal
распоряжаться поток 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);
}
или в качестве альтернативы я должен просто передать в bool
о том, нужно ли распоряжаться или нет?
Это может быть вопрос вкуса, но , лично я предпочел бы ваш второй вариант ('use'). – Heinzi
Я всегда закрывал потоки в области, в которой они были созданы, поэтому, фактически, это отвечает за вызов вызывающего абонента, а не за то, что это происходит в черном ящике реализации метода. Тем не менее, некоторые API .net предлагают флаг, чтобы взять на себя ответственность за удаление ... вы также можете предложить это как необязательный параметр, который по умолчанию равен false. – spender
Обычно я принимаю правило «Код, создающий поток, отвечает за его закрытие». Есть некоторые случаи, когда это неуместно, например, если это оставит поток открытым в течение очень долгого времени. Независимо от того, что вы делаете, важно документировать то, что делает вызывающий, с потоком - это относится к любому параметру, в котором вызывающий объект изменяет состояние поставленного объекта, но люди часто упускают из виду, что кто-то, читающий поток, меняет свое состояние. –