Force subclasses of an interface to implement ToString
C#OopC# Problem Overview
Say I have an interface IFoo
and I want all subclasses of IFoo
to override Object's ToString
method. Is this possible?
Simply adding the method signature to IFoo as such doesn't work:
interface IFoo
{
String ToString();
}
since all the subclasses extend Object
and provide an implementation that way, so the compiler doesn't complain about it. Any suggestions?
C# Solutions
Solution 1 - C#
I don't believe you can do it with an interface. You can use an abstract base class though:
public abstract class Base
{
public abstract override string ToString();
}
Solution 2 - C#
abstract class Foo
{
public override abstract string ToString();
}
class Bar : Foo
{
// need to override ToString()
}
Solution 3 - C#
Jon & Andrew: That abstract trick is really useful; I had no idea you could end the chain by declaring it as abstract. Cheers :)
In the past when I've required that ToString() be overriden in derived classes, I've always used a pattern like the following:
public abstract class BaseClass
{
public abstract string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
}
Solution 4 - C#
Sorry to bury out this old thread from the grave, specially as our dear @jon-skeet already provided his own answer.
But if you want to keep the interface and not use an abstract class, I guess this is still possible by simply having your interface implementing the System.IFormattable interface.
interface IFoo : IFormattable
{
}
The only thing to keep in mind is, to properly implement this IFormattable, the concrete implementation should overwrite the Object.ToString()
as well.
This is clearly explained in this nice post.
Your concrete class is now like
public class Bar : IFoo
{
public string ToString(string format, IFormatProvider formatProvider)
{
return $"{nameof(Bar)}";
}
public override string ToString()
{
return ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
}
Hope this might still help anyone.
Solution 5 - C#
Implementing an interface method implicitly seals the method (as well as overriding it). So, unless you tell it otherwise, the first implementation of an interface ends the override chain in C#.
Abstract class = your friend
Check this question
Solution 6 - C#
I know this doesn't answer your question, but since there is no way to do what you're asking for, I thought I'd share my own approach for others to see.
I use a hybrid of Mark and Andrew's proposed solutions.
In my application, all domain-entities derive from an abstract base-class:
public abstract class Entity
{
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
public override string ToString()
{
return this is IHasDescription
? ((IHasDescription) this).EntityDescription
: base.ToString();
}
}
The interface itself only defines a simple accessor:
public interface IHasDescription : IEntity
{
/// <summary>
/// Creates a description (in english) of the Entity.
/// </summary>
string EntityDescription { get; }
}
So now there's a fall-back mechanism built in - or in other words, an Entity
that implements IHasDescription
must provide the EntityDescription
, but any Entity
can still convert to a string.
I know this isn't radically different from the other solutions proposed here, but I like the idea of minimizing the responsibility of the base Entity
type, so that implementing the description-interface remains optional, but you're forced to actually implement the description-method if you're implementing the interface.
IMHO, interfaces that are implemented by the object
base-class should not "count" as implemented - it would be nice to have a compiler option for that, but, oh well...
Solution 7 - C#
I don't think you can force any sub-class to override any of the base-class's virtual methods unless those methods are abstract.