2016-09-15 5 views
1

はどうすればに次のコードが書かれているのでしょうか? 私は基底クラスを持ち、派生クラスの1つを基底クラスのメソッドの1つをオーバーライドしたいと思っていました。しかし、私はオーバーライドされるメソッドに対して別の署名が必要です(もっと複雑にするために、そのメソッドはループに埋められています)。追加のパラメータでメソッドをオーバーライドする抽象クラスを作成する方法

異なる署名を持つメソッドをオーバーライドするのと同等の処理を行うには、次のコードをどのように正しく構成する必要がありますか?

abstract class ClassBase 
{ 
    public void LoopThroughStuff(int i) 
    { 
     for (i = 0; i < 10; i++) 
     { 
      //DO A BUNCH OF STUFF 
      var k = (something determined in loop) //THIS IS USED IN Class2's DoSomething(i,k) 

      DoSomething(i); //THIS NEEDS TO BE OVERRIDDEN IN Class2 WITH ADDITIONAL PARAMETER, WHICH I KNOW CAN'T BE DONE 

      //DO A BUNCH OF STUFF 
     } 
    } 

    public virtual void DoSomething1(int x) 
    { 
     //DO STUFF 
    } 
} 

public class Class1 : ClassBase 
{ 

} 

public class Class2 : ClassBase 
{ 
    public override void DoSomething1(int j, int k) //I KNOW THIS CAN NOT BE DONE 
    { 
     //DO STUFF 
    } 
} 
+0

あなたは '[]'のparamsオブジェクトを使用できますか? – Thomas

+1

* overload *、オーバーライドしないでください。既存のメソッドにデフォルトのパラメータを追加する。ああ、またはトーマスが言ったこと。 – radarbob

+0

このクラスのパブリックインターフェイスに 'DoSomething(int)'を含めている場合は、このクラスのすべての子孫がこの操作をサポートすることを約束しています。これが意図されていない場合は、代わりにこのメソッドを 'private'にすることを検討してください。これにより、この問題は完全に回避されます。 –

答えて

0

あなたの行っていることに対して相続が過剰である可能性があります。あなたの考えを逆にして、代わりに機能的なスタイルを試してください。

(任意の型の)配列またはリストから開始し、配列の各要素を「マップする」、または変換を実行し、新しい配列またはリストを返すlambaまたはFuncオブジェクトと共にSelectメソッドを使用します。

簡潔
string [] array = {"element1", "element2"}; 

Func<string, string> DoSomething = (x) => x.ToUpper(); 

var result = array.Select(DoSomething); 

以上:

var result = array.Select(x => x.ToUpper()); 
0

PolymorphismのタイプであるFunction overloadingを使用して、次のコードのように、基本クラスを行います(抽象宣言退治を行うのはOKです)。基本的なOOPの開始基準を見つけることができます。here

abstract class ClassBase 
{ 
    public virtual void LoopThroughStuff(int i) 
    { 
     for (i = 0; i < 10; i++) 
     { 
     //DO A BUNCH OF STUFF 

     DoSomething(i); 

     //DO A BUNCH OF STUFF 
     } 
    } 

    public virtual void DoSomething1(int x) 
    { 
     //DO STUFF 
    } 

    public virtual void DoSomething1(int j, int k) 
    { 
    //you can keep this empty, as you will override it in Class2 
    } 

} 


public class Class2 : ClassBase 
{ 

    public override void LoopThroughStuff(int i) 
    { 
    for (i = 0; i < 10; i++) 
    { 
     //DO A BUNCH OF STUFF 
     // set k here as you like 

     DoSomething(i,k); 

     //DO A BUNCH OF STUFF 
    } 
    } 
    public override void DoSomething1(int j, int k) 
    { 
    //DO STUFF 
    } 
} 
+0

ちょっとハッソン、私はどのように "LoSThroughStuff"内の "DoSomething"コールをオーバーライドされたバージョンに変更するのですか? –

+0

私は基本クラス内のループでDoSomething(i)を呼び出す必要があることを理解しています。 1つの整数だけでは、これはロジックを実行し、適切な呼び出し方法を見つけるコンパイラジョブです。 – Hasson

+0

Class2が実行されている場合、DoSomething(i)DoSomething(i、k)と置き換える必要があります。また、Class2のDoSomethingの "k"値がループ中に設定されている場合、実行時にDoSomethingコールにどのように渡されますか? –

3

多くのオプションがあります。ここに1つあります:ジェネリックを使用してください。

abstract class ClassBase<T> 
{ 
    public abstract void DoSomething(T args); 
} 

public class Class1 : ClassBase<Class1Args> 
{ 
    public void DoSomething(Class1Args args); 
} 

public class Class1Args 
{ 
    public int x; 
} 

public class Class2 : ClassBase<Class2Args> 
{ 
    public void DoSomething(Class2Args args); 
} 

public class Class2Args 
{ 
    public int j; 
    public int k; 
} 
+0

ここでジェネリックスは良いアイデアです。 'DoSomething'を' LoopThroughStuff'だけで必要と思われるように 'protected'にしておくことをお勧めします。 –

+0

Class2のDoSomethingの「k」値がループ中に設定されている場合、実行時にDoSomethingコールにどのように渡されますか? –

関連する問題