2016-08-01 2 views
0

配列の派生クラスの数を基本クラスとして保持したいと考えています。 次に、配列をループし、派生クラスに同じDBを受け取る関数を呼び出させますが、それぞれの派生クラスは異なるInterfaceとしてDBを受け取る必要があります。派生した引数を持つオーバーライド関数

このようなケースを実装する別の方法はありますか?このコードはコンパイルされません

public interface IBase 
{ 

} 
public interface IClass1 : IBase 
{ 
    bool[] IsEnable { get; } 
} 

public interface IClass2 : IBase 
{ 
    bool[] IsEnable { set; } 
} 

public class DB : IBase, IClass1, IClass2 
{ 
    public bool[] IsEnable { get; set; } 
} 

public abstract class Base 
{ 
    public virtual void fRun(IBase p_oOb) 
    { 

    } 
} 

class MyClass1 : Base 
{ 
    public override void fRun(IClass1 p_oOb) 
    { 
     Console.WriteLine("MyClass1 fRun."); 
    } 
} 

class MyClass2 : Base 
{ 
    public override void fRun(IClass2 p_oOb) 
    { 
     Console.WriteLine("MyClass2 fRun."); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DB db = new DB(); 
     Base[] classes = new Base[] {new MyClass1(), new MyClass2()}; 
     foreach (var Class in classes) 
     { 
      Class.fRun(db); 
     } 
    } 
} 
+0

なぜオーバーライドされたボディの中に希望のインターフェイスとして 'IBase'をキャストできませんか? – slawekwin

+0

私はそれを行うことができます..しかし、そのような場合には、myClassxはDB全体に対する許可を持っています。 –

+0

'IClassx'が' IBase'から継承している限り、そうではありませんか?おそらく引数の基底を持つために別の偽のインタフェースを作成するかもしれません。 – slawekwin

答えて

0

class MyClass1 : Base 
{ 
    public override void fRun(IClass1 p_oOb) 
    { 
     Console.WriteLine("MyClass1 fRun."); 
    } 
} 

をそれはスロー:

私は何をしようとしたが、オーバーライドは、適切な仮想関数を見つけることができないことを

MyClass1.fRun(IClass1)無効にする適切な方法がありません

基本クラスの関数とは実際に異なる基本クラス関数を上書きすることはできません。

  • IClass1場合、IClass2はその後だけ IBaseと署名を有し、派生渡す(そのまま)IBase由来します。
  • 具体的なタイプで実行したい異なる機能を持っている場合、または特定のクラスで特定のIBaseを受け取るようにする場合は、一般的なものにしてfRunTBaseになります。その場合、あなたはまた、おそらくオプション1によると、あなたのコードを修正する各Base

に正しいIBaseを渡すためにいくつかの余分な抽象化が必要になりますそれができるでしょう:(もIsEnableIBaseに今あることに注意してください)MyClass1MyClass2

public interface IBase 
{ 
    bool[] IsEnable { get; } 
} 
public interface IClass1 : IBase { } 

public interface IClass2 : IBase { } 

public class DB : IBase 
{ 
    public bool[] IsEnable { get; set; } 
} 

public abstract class Base 
{ 
    public virtual void fRun(IBase p_oOb) { } 
} 

class MyClass1 : Base 
{ 
    public override void fRun(IBase p_oOb) 
    { 
     Console.WriteLine("MyClass1 fRun."); 
    } 
} 

class MyClass2 : Base 
{ 
    public override void fRun(IBase p_oOb) 
    { 
     Console.WriteLine("MyClass2 fRun."); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DB db = new DB(); 
     Base[] classes = new Base[] { new MyClass1(), new MyClass2() }; 
     foreach (var Class in classes) 
     { 
      Class.fRun(db); 
     } 
    } 
} 
0

あなたのオーバーライドそれぞれ次のようになりする必要があります:

public override void fRun(IBase p_oOb) 
{ 

} 

それ以外の場合は、最初の仮想メソッドを上書きしません。

あなたは、各クラスのプライベートメソッドを呼び出すためにオーバーライドされたメソッドを使用することができます。ところで

public override void fRun(IBase p_oOb) 
{ 
    if(p_oOb is IMyClass1) // or IMyClass2 respectively 
     private_fRun(p_oOb); 
} 

を。 abstactベースクラス内に何も実装しない場合は、abstract -Keywordメソッドを使用する必要があります。そうすることで、派生クラスはそれを実装する必要があります。

また、クラスはBaseから継承されます。また、インターフェイスIClass1IClass2も実装してはいけません。単なる好奇心から。

0

あなたは、おそらく使用する必要があります。

fRun(IBase p_oOb) 

が異なっている:ので

class C 
{ 
    private MyClass1 _1 = new MyClass1(); 
    private MyClass2 _2 = new MyClass2(); 

    public void fRun(IClass1 p_oOb1, IClass2 p_oOb2) 
    { 
     _1.fRun(p_oOb1); 
     _2.fRun(p_oOb2); 
    } 
} 

クラスCBaseを継承しません

fRun(IClass1 p_oOb1, IClass2 p_oOb2) 

それはそれを継承しなかった場合は、コンパイラはエラーをスローします。

関連する問題