simulate List like hashSet in C# so that List will have noduplicate values
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.Anywh开发者_JS百科ere)))
.List<Advertisements>());
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.
Check out this post. The poster used an extension method to add "AddRange" functionality to HashSet.
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
}
精彩评论