473,473 Members | 1,888 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Generic List object

We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks

Feb 13 '07 #1
7 16649
There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

... just convert the type from
List to Hashtable in this method and then quickly find it.
First: for replacing List<T>, you want to use Dictionary<string, T>,
not Hashtable (using string keys as mentioned). With this done, you
would simply have to update this method to use the dictionary methods
(indexer if you strongly believe the item is in the Dictionary;
TryGetValue if you can't be sure).

However! Changing to Dictionary will change a few things; for
instance, it won't be IEnumerable<Tany more (IIRC it is
IEnumerable<KeyValuePair<TKey,TValue>>, with separate .Keys
and .Values properties). Secondly, the sequence becomes undefined
(Dictionary does not respect insertion order).

Perhaps what you need is something that behaves like a Collection<T>
(since List<Tnot very easy to inherit), but handles an inner
Dictionary? To allow for Add(T), this would mean that the key would
have to be obtainable from the item... hmm...

How about below; is still IEnumerable<T>, etc, but you just need to
update your entities to support the Key, and your search method to use
the indexer (in your case, since no conflict between String and
Int32); if you can't add the Key, then you'd presumably need to change
the Add methods, or use some form of key-provider similar to the hash-
code provider (aka IEqualityComparer<T>).

Marc

using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
static class Program
{
static void Main()
{
IndexedList<string, MyDataitems = new IndexedList<string,
MyData>();
items.Add(new MyData("Item 1"));
items.Add(new MyData("Item 2"));
items.Add(new MyData("Item 3"));

MyData item = items["Item 2"];
}
}

public class MyData : IKeyed<string>
{
// lazy fields instead of properties...
public MyData(string @ref)
{
Ref = @ref;
}
public readonly string Ref; // key should be immutable for
hashtable
public string Name;
public string AddressLine1;
public int Something;

string IKeyed<string>.Key { get { return Ref; } }
}

public interface IKeyed<T{
T Key {get;}
}
public class IndexedList<TKey, TValue: Collection<TValuewhere
TValue : IKeyed<TKey>
{
public TValue this[TKey key] {
get { return _index[key]; }
}
// "get by" for when TKey is int, which causes indexer conflict
public TValue GetByKey(TKey key)
{
return _index[key];
}
public TValue GetByIndex(int index)
{
return base[index];
}
public bool TryGetByKey(TKey key, out TValue value)
{
return _index.TryGetValue(key, out value);
}
public IndexedList(IEqualityComparer<TKeykeyComparer)
{
_keyComparer = keyComparer ?? EqualityComparer<TKey>.Default;
}
public IndexedList() : this(null) { }

private readonly IEqualityComparer<TKey_keyComparer;
private readonly Dictionary<TKey, TValue_index = new
Dictionary<TKey, TValue>();
protected override void InsertItem(int index, TValue item)
{
_index.Add(item.Key, item); // checks unique before adding to
either list
base.InsertItem(index, item);
}

protected override void RemoveItem(int index)
{
_index.Remove(this[index].Key);
base.RemoveItem(index);
}
protected override void ClearItems()
{
_index.Clear();
base.ClearItems();
}
protected override void SetItem(int index, TValue item)
{
TKey oldKey = this[index].Key, newKey = item.Key;
if (_keyComparer.Equals(oldKey, newKey))
{ // key same; update existing
_index[newKey] = item;
}
else if (_index.ContainsKey(newKey))
{ // key changed but now a duplicate
throw new ArgumentException("Duplicate key");
}
else
{ // key changed; remove and re-add
_index.Remove(oldKey);
_index.Add(newKey, item);
}
base.SetItem(index, item);
}
}
Feb 13 '07 #2
IF you want a nice named object, then

public class PersonCollection : System.Collections.Generic.List
<Person>

{

}

Below is something cool I found

I found it at:

http://www.google.com/search?hl=en&q...IteratorAction

Matt Berther

using System;

using System.Collections.Generic;

using System.Text;

namespace HowToDoCollections

{

public delegate void IteratorActionDelegate(object sender , Person per);

public class PersonCollection : System.Collections.Generic.List <Person>

{

public void Iterate(object sender , IteratorActionDelegate action)

{

foreach (Person p in this)

{

action(sender, p);

}

}

}

}

namespace HowToDoCollections

{

public class Person

{

#region Member Variables

private string _firstName = string.Empty;

private string _lastName = string.Empty;

private string _uid = System.Guid.NewGuid().ToString("N");

#endregion

#region Constructors

public Person()

{

}

public Person(string firstName, string lastName)

{

this.FirstName = firstName;

this.LastName = lastName;

}

#endregion

#region Properties

public string FirstName

{

get { return _firstName; }

set { _firstName = value; }

}

public string LastName

{

get { return _lastName; }

set { _lastName = value; }

}

public string UID

{

get { return _uid; } //ReadOnly

}

#endregion

}

}



class Program

{

private static PersonCollection
personCollectionWithLargerThanMethodScope = new PersonCollection();

private static void SayHello(object sender , Person per)

{

Console.WriteLine("Hello, {0} {1}", per.FirstName,
per.LastName);

}

private static void TellUserIWasNotVerified(object sender, Person
per)

{

Console.WriteLine("NOT VERIFIED : {0} {1}", per.UID,
per.LastName + " " + per.FirstName);

}

private static void VerifyAllPersons(object sender, Person per)

{

if (per.FirstName.Length <= 0 || per.LastName.Length <= 0)

{

//you need something that lives outside of the method to
track them

personCollectionWithLargerThanMethodScope.Add(per) ;

}

}

static void Main(string[] args)

{

try

{

PersonCollection p1 = new PersonCollection();

p1.Add(new Person("John", "Smith"));

p1.Add(new Person("Cindy", "Brady"));

p1.Add(new Person("", "Madonna"));

p1.Add(new Person("Mary", "Jones"));

p1.Add(new Person("Cher", ""));

p1.Iterate(System.Environment.UserName , new
IteratorActionDelegate(SayHello));

Console.WriteLine("\n\r\n\r");

p1.Iterate(System.Environment.UserName, new
IteratorActionDelegate(VerifyAllPersons));

personCollectionWithLargerThanMethodScope.Iterate( null, new
IteratorActionDelegate(TellUserIWasNotVerified));

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

finally

{

Console.WriteLine("\n\r\n\rPress ENTER to end.");

Console.Read();

}



}

}
Feb 13 '07 #3
Ammendments:

1: remove _keyComparer (not necessary)

2: in the ctor, initialise the Dictionary as follows: _index = new
Dictionary<TKey, TValue>(keyComparer);

3: replace references to _keyComparer with _index.Comparer

Note that (as per other poster) you can use the Find method on
List<T>, but this still enumerates internally, so O(n); the Dictionary
approach is closer to O(1).

Marc

Feb 13 '07 #4
frick!!! I meant:

_index = new Dictionary<TKey, TValue>(keyComparer ??
EqualityComparer<TKey>.Default);

Feb 13 '07 #5
On Feb 13, 4:05 pm, "Sehboo" <MasoodAd...@gmail.comwrote:
We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks
Hi,

Why not use the generic Dictionary collection instead? It use a
hashtable implementation as well.

Do the contents of the List collections change or are they pretty
static? If they are static then you could sort the list once and use
the BinarySearch method.

Also, did you know there was no need to code your own loop for
searching? List already has the Find method.

Brian

Feb 13 '07 #6
if you have 1,000 of anything; put it in a database

C# does not scale well enough to store 1,000 items in memory


On Feb 13, 2:05 pm, "Sehboo" <MasoodAd...@gmail.comwrote:
We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks

Feb 14 '07 #7
Good to see our local troll has a new face

Feb 15 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: majm | last post by:
I'm trying to implement strongly typed lists in the 2.0 framework. I'm using VS2005 beta 2. So far, System.Collections.Generic.List appears to be the ideal solution. However, the...
0
by: crazyone | last post by:
I've got a gaming framework i'm building and i want to save myself the trouble of reading and writting the complete game data to a custom file and load/save it to an XML file but i'm getting...
4
by: rsa_net_newbie | last post by:
Hi there, I have a Managed C++ object (in a DLL) which has a method that is defined like ... Generic::List<String^>^ buildList(String^ inParm) Now, when I compile it, I get "warning C4172:...
1
by: Deckarep | last post by:
Dear CSharp Group, Both of these techniques work as expected but what is the better way of doing this? Or does it even make a difference? Method 1: public delegate void MyDelegate(string...
3
by: Doug | last post by:
I have a generic list object with a property called, "MarkedForDeletion". During the course of my processing, some of the objects in the list will get this property set to true and so at the end...
7
by: =?Utf-8?B?Sm9lbCBNZXJr?= | last post by:
I have created a custom class with both value type members and reference type members. I then have another custom class which inherits from a generic list of my first class. This custom listneeds...
4
by: tadmill | last post by:
Hi, Is it possible for a generic list class to use Reflection on the generic type being used to detect a property within that type that refers to the same generic class, only with a different...
3
by: Taurin | last post by:
I have a method that I would like to be able to pass a generic list (such as List<string>, List<int>, etc). I'm trying to figure out what would be the best type of parameter to use to pass in the...
6
by: phancey | last post by:
I want to define a class like this class MyClass { List<TMyList<Twhere T : IMyList {get; set;} } or something like this. I don't want to put <Ton my class definition
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.