Принудительные подклассы интерфейса для реализации ToString - программирование
Подтвердить что ты не робот

Принудительные подклассы интерфейса для реализации ToString

Скажем, у меня есть интерфейс IFoo, и я хочу, чтобы все подклассы IFoo переопределили метод Object ToString. Это возможно?

Просто добавление сигнатуры метода к IFoo как таковой не работает:

interface IFoo
{
    String ToString();
}

поскольку все подклассы расширяют Object и обеспечивают реализацию таким образом, поэтому компилятор не жалуется на это. Любые предложения?

4b9b3361

Ответ 1

Я не верю, что вы можете сделать это с помощью интерфейса. Вы можете использовать абстрактный базовый класс:

public abstract class Base
{
    public abstract override string ToString(); 
}

Ответ 2

abstract class Foo
{
    public override abstract string ToString();
}

class Bar : Foo
{
    // need to override ToString()
}

Ответ 3

Джон и Эндрю: этот абстрактный трюк действительно полезен; Я понятия не имел, что вы можете закончить цепочку, объявив ее абстрактной. Приветствия:)

В прошлом, когда я требовал переопределения ToString() в производных классах, я всегда использовал шаблон, подобный следующему:

public abstract class BaseClass
{
    public abstract string ToStringImpl();

    public override string ToString()
    {
        return ToStringImpl();
    }    
}

Ответ 4

Внедрение метода интерфейса неявно запечатывает метод (а также переопределяет его). Итак, если вы не указали иначе, первая реализация интерфейса завершает цепочку переопределения на С#.

Essential.NET

Абстрактный класс = ваш друг

Отметьте этот вопрос

Ответ 5

Я знаю, что это не отвечает на ваш вопрос, но поскольку у вас нет возможности делать то, о чем вы просите, я думал, что поделюсь своим собственным подходом, чтобы другие могли видеть.

Я использую гибрид предлагаемых Марком и Эндрю предложений.

В моем приложении все объекты домена получают из абстрактного базового класса:

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();
    }
}

Сам интерфейс определяет простой аксессор:

public interface IHasDescription : IEntity
{
    /// <summary>
    /// Creates a description (in english) of the Entity.
    /// </summary>
    string EntityDescription { get; }
}

Итак, теперь встроенный механизм возврата - или, другими словами, Entity, который реализует IHasDescription, должен предоставить EntityDescription, но любой Entity может все еще преобразовать в строку.

Я знаю, что это не радикально отличается от других предложенных здесь решений, но мне нравится идея минимизации ответственности базового типа Entity, поэтому реализация интерфейса описания остается необязательной, но вы вынуждены фактически реализовать метод description, если вы реализуете интерфейс.

IMHO, интерфейсы, реализованные базовым классом object, не должны "подсчитываться" как реализованы - было бы неплохо иметь для него параметр компилятора, но, ну, хорошо...

Ответ 6

Я не думаю, что вы можете заставить любой подкласс переопределить любой из виртуальных методов базового класса, если эти методы не являются абстрактными.