假设我有一个接口IFoo
,我希望IFoo
的所有子类都覆盖Object的ToString
方法。这可能吗?
简单地将方法签名添加到IFoo不起作用:
interface IFoo
{
String ToString();
}
因为所有子类都扩展Object
并以这种方式提供实现,所以编译器不会抱怨它。有什么建议吗?
答案 0 :(得分:81)
我不相信你能用界面做到这一点。您可以使用抽象基类:
public abstract class Base
{
public abstract override string ToString();
}
答案 1 :(得分:21)
abstract class Foo
{
public override abstract string ToString();
}
class Bar : Foo
{
// need to override ToString()
}
答案 2 :(得分:8)
Jon&安德鲁:这个抽象技巧真的很有用;我不知道你可以通过宣称它是抽象的来结束链条。干杯:)
过去当我要求在派生类中覆盖ToString()时,我总是使用如下模式:
public abstract class BaseClass
{
public abstract string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
}
答案 3 :(得分:1)
答案 4 :(得分:1)
我知道这不能回答你的问题,但由于没有办法做你所要求的,我想我会分享我自己的方法让别人看。
我使用Mark和Andrew提出的解决方案的混合体。
在我的应用程序中,所有域实体都派生自抽象基类:
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
的{{1}}必须提供IHasDescription
,但任何EntityDescription
仍然可以转换为字符串。
我知道这与此处提出的其他解决方案没有根本的不同,但我喜欢最小化基类Entity
类型的责任的想法,因此实现description-interface仍然是可选的,但是你'如果您正在实现接口,则强制实际实现description-method。
恕我直言,由Entity
基类实现的接口不应该像实现那样“计数” - 为此设置编译器选项会很好,但是,哦......好吧......
答案 5 :(得分:0)
我认为你不能强迫任何子类覆盖任何基类的虚方法,除非这些方法是抽象的。
答案 6 :(得分:0)
很抱歉从坟墓中掩埋这条旧线,特别是作为我们亲爱的@ jon-skeet already provided his own answer。
但是,如果您想保留该接口而不使用抽象类,那么我猜想,仍然可以通过简单地使您的接口实现System.IFormattable接口来实现。
interface IFoo : IFormattable
{
}
唯一要记住的是,要正确实现此IFormattable,具体实现也应覆盖Object.ToString()
。
This is clearly explained in this nice post.
您的具体课程现在就像
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);
}
}
希望这仍然可以帮助任何人。