インターフェースIFoo
があり、IFoo
のすべてのサブクラスでオブジェクトの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()
}
Jon&Andrew:その抽象的なトリックは本当に便利です。あなたがそれを抽象的であると宣言することによって連鎖を終わらせることができるとは思いもしませんでした。乾杯:)
これまで、派生クラスでToString()をオーバーライドする必要があったときは、常に次のようなパターンを使用しました。
public abstract class BaseClass
{
public abstract string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
}
これであなたの質問に答えられないことはわかっていますが、あなたが求めていることをする方法がないので、私は他の人に見てもらうために私自身のアプローチを共有したいと思いました。
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
を実装するIHasDescription
はEntityDescription
を提供する必要がありますが、Entity
はそれでも文字列に変換します。
これがここで提案されている他のソリューションと根本的に異なるわけではないことを知っていますが、基本のEntity
タイプの責任を最小限に抑えて、説明インターフェイスの実装をオプションのままにするというアイデアが好きですが、インターフェイスを実装している場合は、descriptionメソッドを実際に実装します。
IMHO、object
基本クラスによって実装されるインターフェースは、実装として「カウント」されるべきではありません-そのためのコンパイラー・オプションがあればいいのですが、まあ...
特に私たちの親愛なる@ jon-skeet すでに彼自身の答えを提供した として、墓からこの古いスレッドを埋めて申し訳ありません。
しかし、抽象クラスを使用せずにインターフェイスを保持したい場合は、インターフェイスに System.IFormattable インターフェイスを実装するだけで、これはまだ可能だと思います。
_interface IFoo : IFormattable
{
}
_
留意すべき唯一のことは、このIFormattableを適切に実装するには、具体的な実装でObject.ToString()
も上書きする必要があることです。
あなたの具体的なクラスは今のようです
_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);
}
}
_
これがまだ誰にも役立つことを願っています。
これらのメソッドが抽象的でない限り、サブクラスに強制的にoverrideベースクラスの仮想メソッドを強制することはできないと思います。