Ответ 1
Я не верю, что вы можете сделать это с помощью интерфейса. Вы можете использовать абстрактный базовый класс:
public abstract class Base
{
public abstract override string ToString();
}
Скажем, у меня есть интерфейс IFoo
, и я хочу, чтобы все подклассы IFoo
переопределили метод Object ToString
. Это возможно?
Просто добавление сигнатуры метода к IFoo как таковой не работает:
interface IFoo
{
String ToString();
}
поскольку все подклассы расширяют Object
и обеспечивают реализацию таким образом, поэтому компилятор не жалуется на это. Любые предложения?
Я не верю, что вы можете сделать это с помощью интерфейса. Вы можете использовать абстрактный базовый класс:
public abstract class Base
{
public abstract override string ToString();
}
abstract class Foo
{
public override abstract string ToString();
}
class Bar : Foo
{
// need to override ToString()
}
Джон и Эндрю: этот абстрактный трюк действительно полезен; Я понятия не имел, что вы можете закончить цепочку, объявив ее абстрактной. Приветствия:)
В прошлом, когда я требовал переопределения ToString() в производных классах, я всегда использовал шаблон, подобный следующему:
public abstract class BaseClass
{
public abstract string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
}
Внедрение метода интерфейса неявно запечатывает метод (а также переопределяет его). Итак, если вы не указали иначе, первая реализация интерфейса завершает цепочку переопределения на С#.
Абстрактный класс = ваш друг
Отметьте этот вопрос
Я знаю, что это не отвечает на ваш вопрос, но поскольку у вас нет возможности делать то, о чем вы просите, я думал, что поделюсь своим собственным подходом, чтобы другие могли видеть.
Я использую гибрид предлагаемых Марком и Эндрю предложений.
В моем приложении все объекты домена получают из абстрактного базового класса:
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
, не должны "подсчитываться" как реализованы - было бы неплохо иметь для него параметр компилятора, но, ну, хорошо...
Я не думаю, что вы можете заставить любой подкласс переопределить любой из виртуальных методов базового класса, если эти методы не являются абстрактными.