C# 强制接口的子类实现 ToString

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/510341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:13:27  来源:igfitidea点击:

Force subclasses of an interface to implement ToString

c#oop

提问by rjohnston

Say I have an interface IFooand I want all subclasses of IFooto override Object's ToStringmethod. Is this possible?

假设我有一个接口IFoo,我希望所有的子类都IFoo覆盖 Object 的ToString方法。这可能吗?

Simply adding the method signature to IFoo as such doesn't work:

简单地将方法签名添加到 IFoo 是行不通的:

interface IFoo
{
    String ToString();
}

since all the subclasses extend Objectand provide an implementation that way, so the compiler doesn't complain about it. Any suggestions?

由于所有子类都以Object这种方式扩展并提供实现,因此编译器不会抱怨它。有什么建议?

采纳答案by Jon Skeet

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

回答by Andrew Peters

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

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

回答by Frederick The Fool

I don't think you can force any sub-class to overrideany of the base-class's virtual methods unless those methods are abstract.

我认为您不能强制任何子类覆盖任何基类的虚拟方法,除非这些方法是抽象的。

回答by Ric Tokyo

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

实现一个接口方法隐式地密封了该方法(以及覆盖它)。因此,除非您另有说明,否则接口的第一个实现会结束 C# 中的覆盖链。

Essential .NET

基本.NET

Abstract class = your friend

抽象类 = 你的朋友

Check this question

检查这个问题

回答by Mark Simpson

Jon & Andrew: That abstract trick is really useful; I had no idea you could end the chain by declaring it as abstract. Cheers :)

Jon & Andrew:这个抽象的技巧真的很有用。我不知道您可以通过将其声明为抽象来结束链条。干杯:)

In the past when I've required that ToString() be overriden in derived classes, I've always used a pattern like the following:

过去,当我要求在派生类中重写 ToString() 时,我一直使用如下模式:

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

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

回答by mindplay.dk

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.

我使用了 Mark 和 Andrew 提出的解决方案的混合体。

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 Entitythat implements IHasDescriptionmust provide the EntityDescription, but any Entitycan still convert to a string.

所以现在有一个内置的回退机制 - 或者换句话说,Entity实现IHasDescription必须提供EntityDescription,但任何Entity仍然可以转换为字符串。

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 Entitytype, so that implementing the description-interface remains optional, but you're forced to actually implement the description-method if you're implementing the interface.

我知道这与这里提出的其他解决方案没有根本的不同,但我喜欢最小化基Entity类型责任的想法,这样实现描述接口仍然是可选的,但你被迫实际实现描述 -方法,如果你正在实现接口。

IMHO, interfaces that are implemented by the objectbase-class should not "count" as implemented - it would be nice to have a compiler option for that, but, oh well...

恕我直言,由object基类实现的接口不应该“算作”已实现 - 有一个编译器选项会很好,但是,哦......

回答by Seb T.

Sorry to bury out this old thread from the grave, specially as our dear @jon-skeet already provided his own answer.

很抱歉从坟墓中埋葬这个旧线程,特别是因为我们亲爱的@jon-skeet已经提供了他自己的答案

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.IFormattableinterface.

但是,如果您想保留接口而不使用抽象类,我想这仍然可以通过简单地让您的接口实现System.IFormattable接口来实现。

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.

唯一要记住的是,为了正确实现这个 IFormattable,具体的实现也应该覆盖它Object.ToString()

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.

希望这仍然可以帮助任何人。