views:

109

answers:

3

I have a client and a server program, and I am currently using hashtables to store the clients Name and ip address when they connect. I now need to add another variable that the client will send to the server when it connects, but as far as I understand it, hashtables only have 2 columns (Key and value). Is there another way I could store this data instead of using hashtables?

+4  A: 

You can stick objects into hash tables, or dictionaries.

So make yourself a user class of some description and then store your user object in your dictionary under their name.

This would then lend itself to take other properties as and when you need to add them.

public class User
{
    public string Name { get; set; }
    public string IPAddress { get; set; }
    public string AnotherProperty { get; set;}
}


Dictionary<string, User> userTable = new Dictionary<string, User>();

userTable.Add(userName, new User(){Name = "fred", IPAddress = "127.0.0.1", AnotherProperty = "blah"});

Something like this

jimplode
Brilliant, I've got that to work and input the data, but how would I read the data? The username part is easy enough, but the second field is a class. What syntax would I use to extract this data?
Alex Godbehere
You would cast the object, so ((User)userTable["Fred"])
jimplode
I still can't get it to work. When I use just the name of the dictionary, it can't find it, but when I use the name of the class that the dictionary is located in before it (Users.), the first 'Users' becomes underlined and says that it can't convert it into a 'string'. The whole program is here: http://csharp.pastebin.com/0ESB4RYB
Alex Godbehere
Ah... take your dictionary out of the User class. Make it a variable of the form class. Then you should be able to access it directly.
jimplode
Okay, it's now in the Form class, but the first User is still getting highlighted with the error: "Error: Cannot implicitly convert type 'DictionaryExperiment.User' to 'String'"
Alex Godbehere
usersName = ((User)d[userName]).Name; You need to get the property from the user, as the object returned from the dictionary is the User Object, so User.Name is what you want.
jimplode
That worked. Thank you so much! While you're here, would you happen to know how to somehow show all of the entries of the dictionary at once? Maybe in a sort of list view? Or should I make a new question thread?
Alex Godbehere
What kind of application is it?? asp.net, mvc.net, WPF, Winforms?? Depending on what you are using there are many ways.
jimplode
It's a Winforms application. Do you need any other information?
Alex Godbehere
In winforms you can bind to the collection, for example using a listview you can do something like the following: listbox.DataSource = myCollection; then you set the id and display properties, something like listbox.DisplayMember = "Name"; listbox.ValueMember = "IPAddress"; then you would call listbox.DataBind(); there are many tutorials out there for this, http://www.codeproject.com/KB/database/scomlistcontrolbinding.aspx is the first one I found after a google.
jimplode
Have a look at WPF if you can, the control customisation in that is phenominal!!
jimplode
Is myCollection a variable I have to make or is it d? If it is one I have to make, what type is it? Thank you for your help by the way, I really appreciate it.
Alex Godbehere
it is "d" in your case, although I would give this collection a more meaningful name.
jimplode
There is a listbox.DataBindings(), but not a listbox.DataBind(), am I missing a reference?
Alex Godbehere
Sorry, my bad, you do not need the DataBind() method.
jimplode
I feel like I'm bugging you now, but I really can't get this to work. I've attached a screenshot of the error for the sake of simplicity. http://img264.imageshack.us/img264/9131/captureep.png
Alex Godbehere
can you upload a zip of your code somewhere?! I will take a look as I am in a good mood!!
jimplode
http://www.megaupload.com/?d=CYRPUBGI
Alex Godbehere
listbox.DataSource = userDict.Values.ToList();listbox.DisplayMember = "Name";listbox.ValueMember = "IPAddress";
jimplode
Try that, I just made a random collection like this: userDict.Add("Jim", new User() { Name = "Jim", IPAddress = "127.0.0.1", Status = "Status1" }); and then using that code above it worked, the bottom box was populated with names.
jimplode
Brilliant, that works! Now all I need to do is figure out how to remove the user from the list when they are removed from the dictionary, but I'm sure I can figure that out.
Alex Godbehere
It should just remove itself, as it is bound to the collection, failing that just change reassign the source.
jimplode
I just created a new function to update the list. The Program is here if you want to see the final thing: http://www.megaupload.com/?d=FMWXA52R
Alex Godbehere
Glad I could help. :)
jimplode
One actual final thing if you could. When I try and set a text box to the value that's selected by doing txtUser.Text = lstUsers.SelectedValue.ToString(); The textbox turns into "DictionaryExperiment.User" How do I get the actual value?
Alex Godbehere
((User)lstUsers.SelectedValue).Name or ((User)lstUsers.SelectedValue).IPAddress
jimplode
This is because you need to cast the type, by just doing a tostring you are returning the string representation of the object housed in the listbox.
jimplode
That works until I try to add a second entry to the dictionary, then every value in the list view turns into "DictionaryExperiment.User".
Alex Godbehere
Then you did something wrong!! A dictionary stored objects in it, it is a collection of key,value pairs. The key in our case is a string, and the value is a User object. As long as when you add new items you are adding ("string", UserObject) this should work, and when you set the datasource make sure it is for the collection of values, so d.Values.ToList()
jimplode
+1  A: 

Hi there.

You could create a new class specifically for sotring this information e.g.

public class Client
{
    private string Name { get; set;}
    private string IP { get; set;}
    //... etc.
}

Instead of using a HashTable, simply store an instance of the Client class into the Session object (or whatever your using to store the HashTable.)

If you need to store more then one client's details, then use a List<Client>, or a Dictionary if you need to use keys to lookup items. Experiment to see what works for you.

Cheers. Jas.

Jason Evans
A: 

I'm not sure it's the best solution, but just for general knowledge, if you really need a table, you can use DataTable Class which is a part of ADO.NET (which is native to .NET).

The reason this is not advisable is that it doesn't support unique keys, as a dictionary, and that it generally complicates things in your scenario.

Oren A