tags:

views:

237

answers:

3

I want to add colections to List, but only if Advertisements does not already exist in it. I know that HashSet works like this that has no duplicate values, but with HashSet i can not use AddRange and GetRange.

So is it possible to simulate List like hashSet?

List<Advertisements> advertisements = new List<Advertisements>();

advertisements.AddRange(NHibernateSession.CreateCriteria<Advertisements>()
.CreateCriteria(AdvertisementsProperties.City.ToString())
.Add(Restrictions.Or(
Restrictions.Like(CitiesProperties.Name.ToString(), text, MatchMode.Anywhere),
Restrictions.Like(CitiesProperties.SlovenianName.ToString(), text, MatchMode.Anywhere)))
.List<Advertisements>());

advertisements.AddRange(NHibernateSession.CreateCriteria<Advertisements>()
.CreateCriteria(AdvertisementsProperties.Area.ToString())
.Add(Restrictions.Or(
Restrictions.Like(AreasProperties.Name.ToString(), text, MatchMode.Anywhere),
Restrictions.Like(AreasProperties.SlovenianName.ToString(), text, MatchMode.Anywhere)))
.List<Advertisements>());
+4  A: 

To add a bunch of items to a HashSet like AddRange does simply use:

set.UnionWith(items);

The items in a HashSet are not indexed (it's implemented as a hash table which is not designed for index based access to elements). If you strictly need to store items by index, you'll have to use a simple list and create your own Add method that checks Contains on each element before adding it to the underlying list. Of course, a linear list doesn't provide the efficiency of set operations as HashSet does.

Mehrdad Afshari
Unless he needs to preserve insertion order.
SLaks
+1  A: 

Check out this post. The poster used an extension method to add "AddRange" functionality to HashSet.

Matt Dearing
This is a bad thing to do with a `HashSet`. It already provides a means to add an arbitrary `IEnumerable<T>` (possibly more efficiently than adding a sequence one by one).
Mehrdad Afshari
+1  A: 

You'd probably want to create your own class if you often need a hybrid List/Set collection functionality. It would go something like this:

using System;
using System.Collections;
using System.Collections.Generic;

public class ListSet<T> : IList<T>, ISet<T> // ISet<T> is supported only from .NET 4.0 on
{
    #region Inner collections

    private HashSet<T> _innerSet = new HashSet<T>();
    private List<T> _innerList = new List<T>();

    #endregion

    #region The read methods delegate to the inner collection which is more appropriate and efficient:

    public bool Contains(T item)
    {
        return this._innerSet.Contains(item);
    }

    public int IndexOf(T item)
    {
        return this._innerList.IndexOf(item);
    }

    // TODO: Implement all other read operations

    #endregion

    #region The write methods must keep both inner collections synchronized

    public bool Add(T item)
    {
        bool wasAdded = this._innerSet.Add(item);
        if (wasAdded) this._innerList.Add(item);

        return wasAdded;
    }

    public void AddRange(IEnumerable<T> items)
    {
        foreach (T item in items) this.Add(item);
    }

    public bool Remove(T item)
    {
        if (this._innerSet.Remove(item))
        {
            return this._innerList.Remove(item);
        }

        return false;
    }

    // TODO: Implement all other write operations
    // TODO: Consider implementing roll back mechanisms in exception handlers
    //            when write operations fail

    #endregion
}
herzmeister der welten
herzmeister der welten maybe do you have whole class written somewhere becouse it is very interested class? regards
senzacionale