I have parent class (Base) and child class (Derived). Then another interface use Base as the Generic Type and within that interface call IsDataEqual on derived objects.
That interface receives many implementations of this derived object since it use generic with type constraint to Base.
public interface IMyLogic<T> where T : Base
Everything works fine but I feel bad about having this downcast. Is there anyway to avoid it ?
public abstract class Base
{
public abstract bool IsDataEqual(Base data);
}
public class Derived : Base
{
public string x;
public string Y;
public override bool IsDataEqual(Base data)
{
if(data.GetType() != typeof(Derived))
{
//Type mismatch
throw new Exception();
}
Derived derriveData = data as Derived; //downcast
if (this.x == derriveData.x || this.y == derriveData.y)
{
return true;
}
else
{
return false;
}
}
}
p.s. I can not move x and y to base class due to business logic.
CodePudding user response:
For me, I will use IEquatable<T>
to replace your IsDataEqual
. I'm not sure could you change your base class or not but these is for your reference
public abstract class Base : IEquatable<Base>
{
public bool Equals(Base? other)
{
throw new NotImplementedException();
}
}
public class Derived : Base, IEquatable<Derived>
{
public string x;
public string Y;
public bool Equals(Derived? obj)
{
throw new NotImplementedException();
}
}
CodePudding user response:
This kind of comparison suggest value type semantics, so I would suggest using records to get value-based comparison out-of-the-box (requires c#9 or higher).
Unfortunately, though, we don't have a generic constraint for records for you to use in your interface (that would look like public interface IMyLogic<T> where T : record
), but since records can only inherit from other records (see here), it's enough to simply change your base type to a record (you won't need the IsDataEqual()
abstract method anymore, but I'm assuming that's not the only reason for you to have a base class)