Override GetHashCode and Equals.If you are going to compare against only a single field/property in your class then specify that field only like:
public class hitOBject
{
public string v1;
public float v2;
public float v3;
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 ((hitOBject)obj).v1 == this.v1;
}
public override int GetHashCode()
{
return (v1 != null ? v1.GetHashCode() : 0);
}
}
and then you can use:
List<hitOBject> Detected = new List<hitOBject>();
Detected.Add(new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f});
hitOBject secondObject = new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f};
if (Detected.Contains(secondObject))
{
Console.WriteLine("Alread Exists");
}
Since List<T>.Contains uses Equals to compare for equality, the override Equals method will return a bool based on comparison of field v1.
If you are going to have unique values in your List then it is better to use HashSet<T> since it will only allow unique values based on GetHashCode and Equals implementation.
HashSet<hitOBject> Detected = new HashSet<hitOBject>();
Detected.Add(new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f});
hitOBject secondObject = new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f};
Detected.Add(secondObject);
In the above code, at the end, your HashSet will only contain a single item and secondObject will not be added to the HashSet.
If you don't want to override GetHashCode and Equals then you can use a LINQ query to determine if an object exists in your list like:
hitOBject secondObject = new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f};
if (Detected.Any(r => r.v1 == secondObject.v1))
{
//Already exists
}
Another option is to leave your class as it is and implement IEqualityComparer<T> like
private sealed class hitObjectV1EqualityComparer : IEqualityComparer<hitOBject>
{
public bool Equals(hitOBject x, hitOBject y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return string.Equals(x.v1, y.v1);
}
public int GetHashCode(hitOBject obj)
{
return (obj.v1 != null ? obj.v1.GetHashCode() : 0);
}
}
and then you can pass that in your HashSet<T> constructor like:
Also see: General Naming Conventions C# - MSDN
HashSet<hitOBject> Detected = new HashSet<hitOBject>(new hitObjectV1EqualityComparer());
Later adding items
Detected.Add(new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f});
hitOBject secondObject = new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f};
Detected.Add(secondObject);
You will end up with a single item in the HashSet.
You can use that Comparer with List<T>.Contains as well like:
List<hitOBject> Detected = new List<hitOBject>();
var MyEqualityComparer = new hitObjectV1EqualityComparer();
Detected.Add(new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f});
hitOBject secondObject = new hitOBject {v1 = "bob", v2 = 1f, v3 = 2.5f};
if (Detected.Contains(secondObject, MyEqualityComparer))
{
//Already Exists
}
else
{
Detected.Add(secondObject);
}
HashSet, not aList, and overrideEqualsandGetHashCode.