2016-08-09 15 views
0

に接続されているメソッドを定義する適切な方法:強く、私は次のインタフェースを持っているインタフェース

interface IName 
{ 
    string Name { get; } 
} 

そして、いくつかの基本クラスBaseClassの。このクラスのチャイルドは、INameインタフェースを実装することができますが、それらのすべてではありません。

子供がINAMEを実装する場合、以下のように、私はまた、ToStringメソッド()メソッド、すべてのケースについてまったく同じ方法を上書きしたいと思います:

public override string ToString() 
{ 
    return Name; 
} 

それは、ToStringメソッドをオーバーライドするための良い場所(と思われます) INameのインターフェイスになりますが、私はそれがC#で可能ではないと信じています。 ToString()を各クラスで実装することは、コードの冗長性(および時間の無駄)が非常に多いため、悪い考えです。

このような場合の適切な解決策は何ですか?

+4

抽象クラスなどの基本実装を追加します。 –

+0

これは '.Name'を呼び出す代わりにこれを最初に必要とする理由ですか? –

+0

基本クラス(前述)のとおりですが、Inameを実装していない子クラスに影響するため、ToString()を上書きしたくありません。 – wpfnoop

答えて

4

私のような第2のベースクラスを作成することをお勧めしたい:

public abstract class BaseClass 
{ 
    // your base class implementation 
} 

public abstract class NamedBaseClass : BaseClass, IName 
{ 
    public string Name { get; set;} 
    public override string ToString() 
    { 
     return Name; 
    } 
} 

この方法を使用すると、BaseClassのとINAMEの両方を実装するために子供をしたい場合、あなたはNamedBaseClassから継承する必要があります。 あなたの言葉によると、 "INameといくつかのものを実装しているものもあれば、"ではなく、BaseClassはINameを実装すべきではありませんが、何らかの基本実装が必要です。これが私の解決策です。

EDIT:

、あなたはちょうどそれのために無関係な抽象実装を作ることができ、名前を返し、BaseClassのとは何の関係もありません単一のクラスを作る:

public abstract class NameStringClass : IName 
{ 
    public string Name { get; set; } 
    public override string ToString() 
    { 
      return Name; 
    } 
} 
+0

'ToString'オーバーライドを封印してください。 – Lee

+0

あなたはおそらく正しいです、私は決して前に方法を封印する必要はなかったので、私の心には全く来ませんでした。ヒントをありがとう! – MichaelThePotato

+0

これはOKなアプローチですが、複数の基本クラス(オブジェクト以外の共通の祖先を共有しない)でINameを使用したい場合はどうすればよいでしょうか? 私はそれらのすべての実装をしなければならないでしょう... – wpfnoop

1

がcFooとして考えてみましょうINameを持つ子クラスです。そして、cBar親クラス、およびcBazはINameを実装しないクラスです。

public interface IName 
{ 
    string Name { get; } 
} 

public class CBaz : CBar 
{ 

} 

public class CFoo : CBar, IName 
{ 
    public CFoo(string name) 
    { 
     Name = name; 
    } 

    public string Name { get; } 
} 

abstract public class CBar 
{ 
    public override string ToString() 
    { 
     if (this is IName) 
     { 
      var temp = (IName) (this); 
      return temp.Name; 
     } 
     else 
     { 
      return base.ToString(); 
     } 
    } 
} 

[旧回答] インターフェイスは本質的に空であることに注意してください。あなたは、このインタフェースを実装する人がそのような署名のプロパティ/メソッド/フィールド/などを実装する必要があることを意味して、インタフェースが契約の意味をより深く有するものと考える必要があります。

多くのクラスで共通に使用できる実装固有のタスクについては、抽象クラスが適しています。

ロジックのいくつかの種類を解決する必要がある瞬間、実装のゲートウェイを通過する必要があります、いくつかの実装が発生する必要があります、インターフェイスは本質的に空のテンプレートです。これを実装する最も緩やかな方法は、nameプロパティとToStringオーバーライドの両方を含む抽象クラスを使用することです。そこから、後続のすべてのクラスを継承します。

同時に、CBarクラスの抽象クラスを考えることができます。ベースメソッドbase.ToString()を呼び出すだけでなく、 [旧回答の末尾]

+0

あなたはここで名前を返していません...私は何かを見逃しているか、あなたのコードで何かを忘れてしまっていますか? – MichaelThePotato

+0

あなたの基本クラスはすでにその名前を実装しています。だから、cFooもこのプロパティを持ちます。これは多態性の種類の一種です – CJC

+0

あなたはインタフェースINameを継承するだけなのでbase.ToString()を呼び出していますので、これは通常のToString()を呼び出しますので、ここでは何も解決しませんでした... – MichaelThePotato

関連する問題