Let's say I've defined a class MyDisposable : IDisposable
. I know I can provide a hard-coded list of IDisposable
objects to the using
statement:
using (MyDisposable firstDisposable = new MyDisposable(),
secondDisposable = new MyDisposable())
{
// do something
}
Now let's say I have a few methods that perform operations on a collection of my disposable objects, and I want to do this inside a using
statement. It might look like this (but this doesn't work of course because the using block expects one or more IDisposable
objects and I'm passing a single collection object):
using (var myDisposables = GetMyDisposables())
{
foreach (var myDisposable in myDisposables)
{
DoSomething(myDisposable);
DoSomethingElse(myDisposable);
}
}
Here are the other methods just for clarity:
static List<MyDisposable> GetMyDisposables()
{
throw new NotImplementedException(); // return a list of MyDisposable objects
}
static void DoSomething(MyDisposable withMyDisposable)
{
// something
}
static void DoSomethingElse(MyDisposable withMyDisposable)
{
// something else
}
Is there some way I can accomplish this with the using
statement? Or do I do just have to throw out the statement and manually dispose?
You can create custom dynamic objects by using the classes in the System. Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class.
It is definitely a bad idea to use dynamic in all cases where it can be used. This is because your programs will lose the benefits of compile-time checking and they will also be much slower.
The dynamic keyword is new to C# 4.0, and is used to tell the compiler that a variable's type can change or that it is not known until runtime. Think of it as being able to interact with an Object without having to cast it. dynamic cust = GetCustomer(); cust.
One approach that you can take is to make a collection of IDisposable
objects, which is also IDisposable
:
class CollectionOfDisposable<T> : IDisposable where T : IDisposable {
public IList<T> Members {get; private set;}
public CollectionOfDisposable(IEnumerable<T> members) {
Members = members.ToList();
}
public void Dispose() {
var exceptions = new List<Exception>();
foreach (var item in Members) {
try {
item.Dispose();
} catch (Exception e) {
exceptions.Add(e);
}
}
if (exceptions.Count != 0) {
throw new AggregateException(exceptions);
}
}
}
Now you can write this:
using (var myDisposables = GetMyDisposables()) {
foreach (var myDisposable in myDisposables.Members) {
DoSomething(myDisposable);
DoSomethingElse(myDisposable);
}
}
static CollectionOfDisposable<MyDisposable> GetMyDisposables() {
throw new NotImplementedException(); // return a list of MyDisposable objects
}
You'll have to create your own type that implements IDisposable
and accepts a collection of disposable objects in its constructor, holding onto them and disposing of them all when it is disposed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With