Force subclasses of an interface to implement ToString

C#Oop

C# 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#.

Essential .NET

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrjohnstonView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Andrew PetersView Answer on Stackoverflow
Solution 3 - C#Mark SimpsonView Answer on Stackoverflow
Solution 4 - C#Seb T.View Answer on Stackoverflow
Solution 5 - C#Ric TokyoView Answer on Stackoverflow
Solution 6 - C#mindplay.dkView Answer on Stackoverflow
Solution 7 - C#Frederick The FoolView Answer on Stackoverflow