G
Guest
Here is my first attempt at a deterministic collection using Generics,
apologies for C#. I will try to convert to C++/cli.
using System;
using System.Collections.Generic;
using System.Text;
namespace DeterminedGenericCollection
{
// I got tired of copy and pasting IDisposable
// reusable base class
public abstract class Disposable : IDisposable
{
protected bool disposed = false;
// subclass needs to implement these two methods
abstract protected void DisposeManagedResources();
abstract protected void DisposeUnmanagedResources();
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing) // called from Dispose
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
}
disposed = true;
}
~Disposable() // maps to finalize
{
Dispose(false);
}
}
// generic method to invoke
public interface IInvoke
{
void Invoke();
}
// concrete class to store
class PrintWrapper : Disposable, IDisposable, IInvoke
{
protected override void DisposeManagedResources()
{
//Console.WriteLine("Disposed Managed Resources.");
}
protected override void DisposeUnmanagedResources()
{
Console.WriteLine("Disposed Unmanaged Resources.");
}
public void Invoke()
{
if (disposed) { throw new ObjectDisposedException("Wrapper"); }
// mimic some type of unmanaged action
Console.WriteLine("Print.");
}
}
// generic collection
public class JALGenericCollection<T> : Disposable, IInvoke where T :
IDisposable, IInvoke
{
private readonly object syncLock = new object();
private List<T> list = new List<T>();
public JALGenericCollection() { ;}
// ASSERT d is not null
// ASSERT no object holds a reference to
// d outside of this class
// USAGE Add(new MyClass()); ** newed reference idiom **
// where MyClass implements IDisposable and IInvoke
public void Add(T d)
{
if (d != null)
{
lock (syncLock)
{
list.Add(d);
}
}
else { throw new ArgumentException(); }
}
public void Clear()
{
lock (syncLock)
{
foreach (IDisposable d in list)
{
d.Dispose();
}
list.Clear();
}
}
// return an array of immutable Data struct
public void Invoke()
{
if (disposed) { throw new
ObjectDisposedException("JALGenericCollection"); }
// no one can add or delete during this critical section
lock (syncLock)
{
foreach (IInvoke i in list)
{
i.Invoke();
}
}
}
protected override void DisposeManagedResources()
{
lock (syncLock)
{
foreach (IDisposable d in list)
{
d.Dispose();
}
}
}
protected override void DisposeUnmanagedResources()
{
// do nothing
}
}
class Program
{
static void Main(string[] args)
{
using (JALGenericCollection<PrintWrapper> jalg =
new JALGenericCollection<PrintWrapper>())
{
jalg.Add(new PrintWrapper());
jalg.Add(new PrintWrapper());
jalg.Add(new PrintWrapper());
jalg.Invoke();
jalg.Clear();
jalg.Add(new PrintWrapper());
jalg.Invoke();
//jalg.Add(new InvokeWrapper()); // error,not implement
IDispose
//jalg.Add(new DisposeWrapper()); // error, not implement
IInvoke
}
Console.ReadLine();
}
}
}
Have fun!
apologies for C#. I will try to convert to C++/cli.
using System;
using System.Collections.Generic;
using System.Text;
namespace DeterminedGenericCollection
{
// I got tired of copy and pasting IDisposable
// reusable base class
public abstract class Disposable : IDisposable
{
protected bool disposed = false;
// subclass needs to implement these two methods
abstract protected void DisposeManagedResources();
abstract protected void DisposeUnmanagedResources();
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing) // called from Dispose
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
}
disposed = true;
}
~Disposable() // maps to finalize
{
Dispose(false);
}
}
// generic method to invoke
public interface IInvoke
{
void Invoke();
}
// concrete class to store
class PrintWrapper : Disposable, IDisposable, IInvoke
{
protected override void DisposeManagedResources()
{
//Console.WriteLine("Disposed Managed Resources.");
}
protected override void DisposeUnmanagedResources()
{
Console.WriteLine("Disposed Unmanaged Resources.");
}
public void Invoke()
{
if (disposed) { throw new ObjectDisposedException("Wrapper"); }
// mimic some type of unmanaged action
Console.WriteLine("Print.");
}
}
// generic collection
public class JALGenericCollection<T> : Disposable, IInvoke where T :
IDisposable, IInvoke
{
private readonly object syncLock = new object();
private List<T> list = new List<T>();
public JALGenericCollection() { ;}
// ASSERT d is not null
// ASSERT no object holds a reference to
// d outside of this class
// USAGE Add(new MyClass()); ** newed reference idiom **
// where MyClass implements IDisposable and IInvoke
public void Add(T d)
{
if (d != null)
{
lock (syncLock)
{
list.Add(d);
}
}
else { throw new ArgumentException(); }
}
public void Clear()
{
lock (syncLock)
{
foreach (IDisposable d in list)
{
d.Dispose();
}
list.Clear();
}
}
// return an array of immutable Data struct
public void Invoke()
{
if (disposed) { throw new
ObjectDisposedException("JALGenericCollection"); }
// no one can add or delete during this critical section
lock (syncLock)
{
foreach (IInvoke i in list)
{
i.Invoke();
}
}
}
protected override void DisposeManagedResources()
{
lock (syncLock)
{
foreach (IDisposable d in list)
{
d.Dispose();
}
}
}
protected override void DisposeUnmanagedResources()
{
// do nothing
}
}
class Program
{
static void Main(string[] args)
{
using (JALGenericCollection<PrintWrapper> jalg =
new JALGenericCollection<PrintWrapper>())
{
jalg.Add(new PrintWrapper());
jalg.Add(new PrintWrapper());
jalg.Add(new PrintWrapper());
jalg.Invoke();
jalg.Clear();
jalg.Add(new PrintWrapper());
jalg.Invoke();
//jalg.Add(new InvokeWrapper()); // error,not implement
IDispose
//jalg.Add(new DisposeWrapper()); // error, not implement
IInvoke
}
Console.ReadLine();
}
}
}
Have fun!