Reputation: 8756
Suppose you have the following Generic class heirarchy:
public abstract class GenericBase<T>
{
T SomeProperty{ get; set; }
}
public class Foo<T>
{
T SomeProperty{ get; set; }
}
public abstract class GenericChild<T> : GenericBase<T>
{
// ...
public bool DoSomething(Foo<T> foo)
{
// This is invalid:
return SomeProperty == foo.SomeProperty;
}
}
The equality check in the DoSomething method won't compile. It produces the following error:
Operator '==' cannot be applied to operands of type 'T' and 'T'
If it's releveant, these classes are in separate files. What's the best workaround to allow this kind of equality comparison? Is there some kind of pattern or something to allow this in C#?
Update:
A few of the answers suggest using a:
where T : SomeClass
Unfortunately, very often T will be a primitive type.
Upvotes: 2
Views: 204
Reputation: 112762
Try this:
public abstract class GenericBase<T>
where T : IEquatable<T>
{
public T SomeProperty { get; set; }
}
public class Foo<T>
{
public T SomeProperty { get; set; }
}
public abstract class GenericChild<T> : GenericBase<T>
where T : IEquatable<T>
{
// ...
public bool DoSomething(Foo<T> foo)
{
// This is valid:
return SomeProperty.Equals(foo.SomeProperty);
}
}
C# does not know if == can be applied to T.
Upvotes: 2
Reputation: 3095
If you want to compare objects of type T, you can use IEqualityComparer interface (compares to given objects of given type) or force T to implement IEquatable (allows object to be compared with object of type T)
Upvotes: 0
Reputation: 126982
==
is not generically applicable for all types. It can only be used if T is constrained to a type that supports it, such as where T : class
. However, you would probably be better served using the Equals
method.
return SomeProperty.Equals(foo.SomeProperty);
With the applicable null checking applied.
Upvotes: 8
Reputation: 2035
If you want to do this, you have to hint which type T is of.
For example:
public abstract class GenericBase<T> where T : MyClass
{
T SomeProperty{ get; set; }
}
public class Foo<T> where T : MyClass
{
T SomeProperty{ get; set; }
}
public abstract class GenericChild<T> : GenericBase<T> where T : MyClass
{
}
In your MyClass class you could implement the IEquatable interface, so you can do SomeProperty.Equals(foo.SomeProperty)
If you do not add the where constraint, you still could use the object.Equals
Upvotes: 1