0

I have a simple class called User :

public class User
{
    public int ID { get; set; }
    public int MI { get; set; }

    public User(int id, int mi)
    {
        ID = ID;
        MI = mi;
    }
}

And later on, I have a HashSet of Users that I want to get the ID's from and assign to a in HashSet as follows :

    HashSet<Users> _users = new HashSet<>();
    //code where several User objects are assigned to _users
    HashSet<int> _usersIDs = new HashSet<int>();
    _usersIDs = _users.Select("ID")

But this doesn't work, how can I successfully assigned all of the int ID's in _users to a new HashSet?

MattTheHack
  • 1,354
  • 7
  • 28
  • 48

1 Answers1

1

You can do:

HashSet<int> _usersIDs = new HashSet<int>(_users.Select(user=> user.ID));

But you should override GetHashCode for your User class if you are going to use it in a HashSet<T> and possibily Eqauls as well like:

public class User
{
    protected bool Equals(User other)
    {
        return ID == other.ID && MI == other.MI;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((User) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (ID*397) ^ MI;
        }
    }

    public int ID { get; set; }
    public int MI { get; set; }

    public User(int id, int mi)
    {
        ID = id; //based on @Jonesy comment
        MI = mi;
    }
}
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 1
    Should the hash code really depend on `ID` and `MI`? They're mutable properties, if they change after an item has been added to the hashset, the user will suddenly be in the wrong bucket and become unretrievable. – dcastro Nov 21 '14 at 15:13
  • In other words, if you're gonna drop instances of `User` intro a hash set or use them as keys in a dictionary, it might be a good idea to make the type immutable. – dcastro Nov 21 '14 at 15:14
  • "and possibly Equals as well" ... actually, the documentation says that if you override one, you should override the other. As I recall, Visual Studio (or perhaps the compiler) makes that mandatory. http://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx – Jim Mischel Nov 21 '14 at 15:16
  • 1
    This, or don't use `HashSet`, since there is no immutable property. My point was, a `HashSet` without overridden GetHashCode is of no use. More on...http://stackoverflow.com/a/19721436/961113 – Habib Nov 21 '14 at 15:17
  • 1
    @JimMischel, there is no restriction from compiler. `Derived classes that override GetHashCode must also override Equals to guarantee that two objects considered equal have the same hash code; otherwise, the Hashtable type might not work correctly.`. That is why I said "possibly". If you only implement any one of them, there won't be any error, since `virtual` method from base class would be used. But They will not work properly. – Habib Nov 21 '14 at 15:19