Remove will work with specific items, but you should make sure to keep Reference types and Value types straight or you may not get the behavior you're expecting.
Let's say GameState is a Value type (C# struct). gameStateList.Remove(gameState) will remove an entry from the list if the contained gameState has an equivalent Id (and other equivalent members).
Now, let's say GameState is a Reference type (C# class). gameStateList.Remove(gameState) will remove an entry from the list if the contained gameState is referencing the same object.
In C++ terms, the struct version of GameState will get removed from the list if it's contents are the same. But in the class version of GameState, it will only be removed if the pointers are the same.
Depending on how you do things, you might never notice an issue. Considering GameState as a Class... If you new'ed up single instances of gameState's and used these everywhere in your game you'd probably be fine for a long time. But then if you had SaveGame logic, when you serialize your GameState's out and then load them back in, the reference types would no longer be the same reference even though they have the same guid Id internally.
Here's a little example:
using System;
using System.Collections.Generic;
namespace GameDevExample
{
class Program
{
// Value type Game State
public struct GameStateStruct
{
public Guid Id { get; set; }
}
// Reference Type Game State
public class GameStateClass
{
public Guid Id { get; set; }
}
static void Main(string[] args)
{
// We'll use the same guid for all GameStates.
Guid id = new Guid();
// GameStateStruct is a Value type, so List.Remove will take the item out of the list if the contained item's members are equal.
List<GameStateStruct> gameStateStructList = new List<GameStateStruct>();
GameStateStruct gameStateStruct1;
GameStateStruct gameStateStruct2;
gameStateStruct1 = new GameStateStruct();
gameStateStruct1.Id = id;
gameStateStructList.Add(gameStateStruct1);
Console.WriteLine(string.Format("Struct List contains {0} items.", gameStateStructList.Count));
gameStateStruct2 = new GameStateStruct();
gameStateStruct2.Id = id; // Assign the same Id to struct 2 as we did for struct 1
gameStateStructList.Remove(gameStateStruct2); // And this WILL remove the item from the list.
Console.WriteLine(string.Format("Struct List contains {0} items.", gameStateStructList.Count));
// GameStateClass is a Reference type, so List.Remove will take the item out of the list if the contained item references the same object
List<GameStateClass> gameStateClassList = new List<GameStateClass>();
GameStateClass gameStateClass1;
GameStateClass gameStateClass2;
gameStateClass1 = new GameStateClass();
gameStateClass1.Id = id;
gameStateClassList.Add(gameStateClass1);
Console.WriteLine(string.Format("Class List contains {0} items.", gameStateClassList.Count));
gameStateClass2 = new GameStateClass();
gameStateClass2.Id = id; // Assign the same Id to Class 2 as we did for Class 1
gameStateClassList.Remove(gameStateClass2); // And this WILL NOT remove the item from the list.
Console.WriteLine(string.Format("Class List contains {0} items.", gameStateClassList.Count));
Console.WriteLine("Hit enter to continue");
Console.ReadLine();
}
}
}