Static typed Ids (integers) in C# Within our application I need to work a lot with simple IDs (just integers). 

They are used to make queries against a database. For performance reasons I don't want to materialize them to Entities before the query.

Example:

// not really *that* static typed
public void DoQuery(int userId, int groupId)
{
}


Because I want to make our application more static typed (preventing errors like accidentally switching parameters around), I'm looking for a way to make this all more static typed, like:

public struct UserId
{
     int _UserId;

     public UserId(int userId)
     {
          _UserId = userId;
     }

    public static implicit operator int (UserId userId)
    {
        return userId._Id;
    }
}


and then:

// will throw compilation errors when I try to shoehorn a UserId into a GroupId
public void DoQuery(UserId userId, GroupId groupId)
{
}



Do I need to override equals operators and hascode, or would this be enough?
Are there any important performance penalties (during a highload)? For i.e. garbage collection.
What could be any more negative consequences from this?
Do I need to override equals operators and hascode, or would this be enough?


Structs automatically implement Equals() and GetHashCode(), but that implementation is slow. If you're actually going to use them (even indirectly, e.g. by using some LINQ methods), and you care about performance, you should override them.


  Are there any important performance penalties (during a highload)? For i.e. garbage collection.


There shouldn't be. GC doesn't get involved (unless you're going to box the values, but that's the same for integers).

I'm not sure if the runtime can optimize code using UserId as well as it could for an integer, so for performance critical code, you should make sure it's okay by profiling.


  What could be any more negative consequences from this?


I think this is not a usual pattern in C#, so one negative consequence might be some confusion by your coworkers.