Click here to Skip to main content
15,891,513 members
Articles / Programming Languages / C#
Article

Generic collections extended from Iesi.Collections

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
20 Feb 20064 min read 110.2K   593   32   19
An implementation of a generic ISet for .NET 2.0 based on JasonSmith's ISet.

Introduction

This simple library is developed for working with NHibernate 1.1 or lower. If there is no benefit of having a generic Set<T> that also implements Iesi.Collections.ISet from NHibnernate, you might be more interested in the C5 collection library or the PowerCollection.

This is a simple extension to JasonSmith's Iesi.Collections to offer a generic version of the ISet and its implementations. Also included are five wrappers which help in using old non-generic collections as generic collections. This could be helpful if you want to wrap a non-generic collection from an old application as generic ones in your application.

Like in .NET 1.1, there is need for a generic ISet in the .NET 2.0 environment. There are already some implementations based on JasonSmith's famous Iesi.Collections.ISet. One of them was found on NHibernate' JIRA which is, according to G77 (thanks!), authored by David Marquam. The implementation of this article is basically a modified version of that implementation. I would like to make it clear that most of the credit of this extension goes to him. I posted this version here so that more people can take advantage of this nice work.

However, David's implementation could not perfectly meet our needs because of several facts:

  1. The ISet<T> in this implementation also inherits the ISet. This inheritance caused the lost of the type safe characteristic that a generic collection normally has.
  2. The ISet<T> does not have the bool Add(T o) method like the ISet has. It only has the void ICollection<T>.Add(T o); the ability to tell whether the item has been actually added might be missed.
  3. The generic extension was included in the assembly of JasonSmith’s Iesi.Collection, which makes some difficulty in working with the original Iesi.Collection.

Using the code

Thus I decided to modify this implementation so that the ISet<T> looks like the following:

C#
public interface ISet<T> : ICollection<T>, ICloneable {…}

In the meantime, I think it could be very helpful if the base Set class still implements the ISet interface since it has been widely applied, including by NHibernate. In this way, you can still have the collection mapped by NHibernate.

C#
public abstract class Set<T> : ISet<T>, ISet {…}

As a reminder, here is the declaration of ISet from Iesi.Collections:

C#
public abstract class ISet : ICollection, ICloneable {…}

For the usage of this ISet<T>, please refer to JasonSmith's article about his Iesi.Collections.

Since Set<T> brought the scenario where a generic collection needs to work with old non-generic collections, I added five simple wrappers:

C#
public struct EnumeratorWrapper<T> : IEnumerator<T>{…}
public class EnumerableWrapper <T> : IEnumerable<T>
public sealed class SetWrapper<T> : ISet<T>
public class CollectionWrapper<T> : EnumerableWrapper<T>, ICollection<T>
public class ListWrapper<T> : EnumerableWrapper<T>, IList<T>

These wrappers support using regular collections under a generic collection interface by wrapping the regular collection as an inner collection and delegate all the functions to it. Also, the Equals() of the wrapper are also overridden to delegate to the wrapped, so that wrapperA.Equals(wrapperB) will return true when and only when wrappedA.Equals(wrappedB) is true. The usage of these wrappers are very simple, here is a sample code:

C#
IList = new ArrayList(3);
list.Add("one");
list.Add("two");
list.Add("three");

ICollection<string> cln = new CollectionWrapper<string>(list);
IEnumerable<string> enl = new EnumerableWrapper<string>(list);
IList<string> lst = new ListWrapper<string>(list);

The Iesi.Collections.Generic is in an independent assembly so that use can have more flexibility with using this together with the Iesi.Collection.Generic.

I will keep working on the implementations since my development greatly relies on them.

Important Notes

  1. This implementation is based on the source code from NHibernate which does not override the Equals method, so the a.Equals(b) in this implementation will only return true if a==b;.
  2. The generic SynchornoizedSet has not been implemented yet.

Latest Update:

Feb 6, 06

I added the Iesi.Collections.Test from Nhibernate1.0.2.0. 67 out of the 87 tests were passed using the generic implementation.

The four ExclusiveOR tests could not be passed before I did a very minor modification to the original Iesi.Collections: in the original Set, the method ExclusiveOr was written as follows:

C#
public static ISet ExclusiveOr(ISet a, ISet b)
{
    if(a == null && b == null)
       return null;
     else if(a == null)
       return (Set)b.Clone();
     else if(b == null)
        return (Set)a.Clone();
     else
       return a.ExclusiveOr(b);
}

Note that the clones of a and b are unnecessarily down cast to Set. While, in the Union method of this class, these two clones are down cast to ISet. I modify the original code as follows:

C#
return (ISet)b.Clone();
...
return (ISet)a.Clone();

After this modification, the Iesi.Collection still passes all the Iesi.Collection.Test, and the generic implementation also passes the four ExclusiveOr tests.

Latest update: This small bug of Iesi.Collection.Set has been fixed in the NHibernate version 1.1-alpha1 [ 10081 ], so you don't need to worry about this problem if you are using Iesi.Collection from the later versions of NHibernate.

There are still 16 tests that cannot be passed. They are all operator tests. Since operators can only be used between classes not interfaces, the operator tests down cast the ISet to Set to do the tests, and our generic implementation cannot be downcast to the non-generic Set which causes the failure of the 16 tests.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionExample needed for NHibernate Pin
Gokcer Gokdal15-Dec-06 14:03
Gokcer Gokdal15-Dec-06 14:03 
AnswerRe: Example needed for NHibernate Pin
Kailuo Wang16-Dec-06 5:22
Kailuo Wang16-Dec-06 5:22 
GeneralRe: Example needed for NHibernate Pin
Helmut Meyer18-Sep-09 1:18
Helmut Meyer18-Sep-09 1:18 
GeneralDebbuger Support Pin
alon.albert10-Sep-06 15:16
alon.albert10-Sep-06 15:16 
GeneralRe: Debbuger Support Pin
Kailuo Wang10-Sep-06 18:03
Kailuo Wang10-Sep-06 18:03 
GeneralRe: Debbuger Support Pin
alon.albert10-Sep-06 20:42
alon.albert10-Sep-06 20:42 
GeneralRe: Debbuger Support Pin
Kailuo Wang11-Sep-06 6:25
Kailuo Wang11-Sep-06 6:25 
GeneralRe: Debbuger Support Pin
alon.albert11-Sep-06 7:13
alon.albert11-Sep-06 7:13 
QuestionWhat about license? Pin
D_Guidi4-May-06 11:42
D_Guidi4-May-06 11:42 
AnswerRe: What about license? Pin
Kailuo Wang4-May-06 15:56
Kailuo Wang4-May-06 15:56 
GeneralRe: What about license? Pin
D_Guidi4-May-06 21:05
D_Guidi4-May-06 21:05 
GeneralBinding ListBox to ListWrapper Pin
John Greek23-Feb-06 4:48
John Greek23-Feb-06 4:48 
GeneralRe: Binding ListBox to ListWrapper Pin
Kailuo Wang23-Feb-06 5:13
Kailuo Wang23-Feb-06 5:13 
GeneralRe: Binding ListBox to ListWrapper Pin
John Greek23-Feb-06 6:12
John Greek23-Feb-06 6:12 
GeneralRe: Binding ListBox to ListWrapper Pin
Kailuo Wang23-Feb-06 7:20
Kailuo Wang23-Feb-06 7:20 
QuestionI'm unclear about how to use this in my NHibernate Project Pin
Greg Banister20-Feb-06 7:42
Greg Banister20-Feb-06 7:42 
AnswerRe: I'm unclear about how to use this in my NHibernate Project Pin
Greg Banister20-Feb-06 9:36
Greg Banister20-Feb-06 9:36 
NewsCorrections to facts of ISet origin Pin
G775-Feb-06 3:41
G775-Feb-06 3:41 
GeneralRe: Corrections to facts of ISet origin Pin
Kailuo Wang5-Feb-06 5:50
Kailuo Wang5-Feb-06 5:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.