2011-07-21 10 views
2

この質問に対する回答を見つけるのは難しく、既に質問されている場合はおそらく間違っています。私は、抽象基本クラスと派生クラスを持っています。パラメータとして抽象基本クラスを使用してインターフェイスメソッドを実装するときに派生クラスプロパティにアクセスする

interface IDoSomethingWithFoos 
{ 
    void DoSomethingWithFoo(Foo fooey); 
} 
:今

class Fum : Foo 
{ 
    public int UniqueProperty { get; set; } 
} 

私は抽象基本クラスを取るメソッドとのインタフェースを持っている:

abstract class Foo 
{ 
    protected int property1 
    protected int property2 
// etc.. 
} 

私derviedクラスは、基本クラスでは見られないいくつかの余分なプロパティが含まれています

インターフェイスを実装するクラス

class FumLover : IDoSomethingWithFoos 
{ 
    void DoSomethingWithFoo(Foo fooey) 
    { 
     // now in here i know i am going to be passed objects of Fum 
     // and i want to access its unique properties 

     fooey.UniqueProperty = 1; // this doesn't work 

     ((Fum)fooey).UniqueProperty = 1; // this seems to work 

     // as does.. 

     Fum refToFum = fooey as Fum; 
     refToFum.UniqueProperty = 1; 

    } 
} 

私の質問は次のとおりです:これについては正しい方法で行っていますか?これはコンパイルされますが、実際には正しく動作するかどうかを確認するのに十分なコードがありません。そして私の他の質問は、この悪いデザインですか?より良い方法がありますか?

*

あなたは、インターフェイスメソッドの代わりにはFooのFUMを取るている、FUMを渡ししようとしている場合は自然な反応は、あるので、もう少し詳しく説明し。

私のFumLoverクラスでは、メソッドDoSomethingWithFooは抽象バスクラスのプロパティで95%を処理しています。そして、Fieという別の派生クラスがあるとしましょう。これにはいくつかの固有のプロパティがあります。ここで、FieLoverクラスがあるとしましょう。ここで行うことの95%がFooに適用される可能性があるため、DoSomethingWithFooを実装したいと考えていますが、もう少しFieに固有のことが少しあります。

代替手段は何ですか。それぞれIDoSomethingWithFums、IDoSomethingWithFiesなどのインターフェースを用意するには?私はその違いの5%だけ抽象化をすべて失うようです。

答えて

3
// now in here i know i am going to be passed objects of Fum 
    // and i want to access its unique properties 

これは、設計変更が役立つかもしれないという手掛かりです。現在のインターフェイスには「Foo sで作業中です」と表示されています。実装がFumでしか機能しない場合は、あなたが言っていることとやっていることに不一致があります。 Fumを実際にしか期待していない場合は、インターフェイスのパラメータをFumとして宣言してください。

誰かがちょっと、インターフェースは、彼らが言うので、彼らはFoo(に渡すことができると考えたとき、あなたは例外をスローしませんので、あなたは、その後、as構文を使用することが好ましいことはしたくない場合缶)

asコードは次のようになります。

Fum fumObj = fooey as Fum; 
if (fumObj != null) 
    fumObj.UniqueProperty = 1; 

更新

派生クラスごとのインターフェースの提案は実際には望ましいです(彼らは実際に何を言っているのか分かりません)。しかし、ここで一歩踏み出しましょう。実際にここで何を達成しようとしていますか?もしIDoSomethingWithFoosFooの場所を基本クラス(抽象的なものではあるが)として利用したいのであれば、DoSomethingWithFooを呼び出すことはすべてFooで意味があることを保証する必要がある。ない場合は、FooLoverするを主張にもかかわらず、あなたが本当に唯一Fumの愛以来、あなたはすでに、失ってしまった(またはFie複数可。)

一つの解決策は、Foo自体にabstract DoSomething()メソッドを宣言したことになります。さて、あなたはList<Foo>を持っており、このようなコードかもしれない:

foreach (Foo foo in fooList) 
    foo.DoSomething(); 

は今、あなたが実際に抽象化の利点を取っているし。どのような種類のFooでも問題ありません。派生クラスのみに固有のプロパティに基づいている可能性があります(キャスティングは必要ありません)。

+0

hmmですが、私が間違っていれば修正しますが、インターフェイスは抽象クラスを取るので、常にFumや他のクラスのインスタンスで動作します。いくつかの固有のプロパティを追加しない場合、抽象クラスからクラスを派生させるポイントは何ですか?インターフェイスは「私はこの抽象基底クラスの派生クラスで動作しなければならないが、その独自の側面ではない」とほぼ同じです。 – suite16

+0

これは当てはまりますが、通常、派生していないバージョンの型を受け入れるメソッドがある場合、より多くの派生プロパティにアクセスすることなくその型を行うことができると期待しています。これは必ずしも真実ではありません(通常、APIを公開しているとき)が、それはよくあります。私の主張は、あなたの実装が*派生型の*情報を必要とする場合、そのようなパラメータを宣言すると参考になるかもしれません。私が上で述べたように、あなたがそれを気にしないならば(少なくとも完全にうまくいけば)、少なくとも 'as'オプションを使います。したがって、あなたは不要な例外を投げかけません。 – dlev

+0

@ suite16それは、インターフェイスが何を言っているのか(kind of)です。それぞれの派生クラスは異なる方法で動作させることができますが、1つの実装に固有のプロパティやメソッドについて知っていれば、最初は基本クラスを使用する利点がありません。 –

-1

Fumが拡張しているあなたはそれをあなたのようにキャストできるはずです。

もう1つの方法は、IFooインターフェイスを実装し、代わりにそのメソッドに渡すことです。

+0

「Fum」ではない「Foo」を渡すとどうなりますか?このコードは、キャストに失敗したときに例外をスローします。また、いつも 'Fum'として使用したいのであれば、' Foo'と宣言するのはなぜですか? –

+0

いつも 'Fum'を渡したくない場合はどうすればいいですか? 'Foo'から派生した他のクラスをお持ちの場合はどうなりますか?あなたの解決策には前向きな考え方が含まれていません。クラスへのアクセスを試みる前に 'null'オブジェクトをチェックすることを知っているクラス継承について知っているという事実を考えれば、私は考えているでしょう。また、 'Foo'以外のクラスを渡すとコンパイルされません。親切に-1を削除してください。 – simonlchilds

+0

PS私は列車を待っている間に私の答えを書いた。したがって、コードスニペットはありません。 – simonlchilds

関連する問題