c# - MoreLinq Acquire. What does it do? -
i inspecting jon skeet's morelinq , became curious acquire extension source code
/// <summary> /// ensures source sequence of <see cref="idisposable"/> /// objects acquired successfully. if acquisition of /// 1 <see cref="idisposable"/> fails /// acquired till point disposed. /// </summary> /// <typeparam name="tsource">type of elements in <paramref name="source"/> sequence.</typeparam> /// <param name="source">source sequence of <see cref="idisposable"/> objects.</param> /// <returns> /// returns array of acquired <see cref="idisposable"/> /// object , in source order. /// </returns> /// <remarks> /// operator executes immediately. /// </remarks> public static tsource[] acquire<tsource>(this ienumerable<tsource> source) tsource : idisposable { if (source == null) throw new argumentnullexception("source"); var disposables = new list<tsource>(); try { disposables.addrange(source); return disposables.toarray(); } catch { foreach (var disposable in disposables) disposable.dispose(); throw; } }
from understanding receives ienumerable<idisposable>
, creates list<idisposable>
.
i can't grasp whatever can go wrong here.
can explain me, , possibly provide example extension can useful?
the call addrange
iterates on source
. if reason encounters exception, had been acquired disposed. consider example:
var filenames = new[] { "file1.xml", "file2.xml", "doesnotexist.xml" }; var disposables = filenames.select(fn => file.openread(fn)); var filestreams = disposables.acquire();
no exception thrown when you're assigning disposables
, because of lazy evaluation. however, when call addrange
inside aquire
reaches third element (where tries open "doesnotexist.xml"
), filenotfoundexception
thrown. when happens, acquire
safely dispose previous streams. simple tolist
/ toarray
leave first 2 file streams open.
in essence, acquire
there ensure either all files in filenames
safely opened, or none of them are.
Comments
Post a Comment