2016-03-19 2 views
-1

私は継承クラスを持っていますが、イベントメソッドの引数タイプを継承クラスでもある別のタイプに変更しようとしています。C# - オーバーライドメソッドの引数タイプを変更する

元クラス:

public class Alpha { 
    protected virtual void OnSpecialEvent(AlphaArgs e); 
} 

public class AlphaArgs { 
    public AlphaArgs (int a, object b); 

    public int A { get; } 
    public object B { get; } 
} 

私の継承クラス:

public class Beta : Alpha { 
    protected override void OnSpecialEvent (BetaArgs e) 
    { 
     /* Do Stuff */ 
    } 
} 

public class BetaArgs : AlphaArgs { 
    public BetaArgs (int a, object b, string c) : base (a, b) 
    { 
     /* Do Stuff */ 
    } 

    public string C { get; } 
} 

しかし、私はエラーで終わる:

CS0115 'Beta.OnSpecialEvent(BetaArgs)': no suitable method found to override 

私はAlphaArgsを使用している場合は、私が持っていません問題はありますが、私は追加したいパラメータよりも余分なパラメータを失います。

は私が欠けている明白な何かがあり、私も、私はあなたが、基本クラスのメソッドをオーバーライドしたい時はいつでも、あなたがそれを上書きするために必要なため...

答えて

0

探しているのか分かりません基本クラスと同じシグネチャ。また、メソッドをオーバーライドするのではなく、オーバーロードしています。ただし、次の操作を行うことができます

protected override void OnSpecialEvent(AlphaArgs e) 
{ 
    BetaArgs be = e as BetaArgs; 
    if(be != null) 
    { 
     /* Do Stuff */ 
    } 
    base.OnSpecialEvent(e) 
} 

またはあなたが好むならば、あなたが過負荷OnSpecialEventを作成することができます。

protected void OnSpecialEvent(BetaArgs e) 
{ 
    BetaArgs be = e as BetaArgs; 
    if(be != null) 
    { 
     /* Do Stuff */ 
    } 
} 

詳細については、こちらをご覧ください。 https://stackoverflow.com/a/27547235/1926877

希望すると、これが役立ちます。

+0

:BetaArgsはなし、継承チェーンのさらに下にあるので、私はBetaArgsパラメータをOnSpecialEvent渡すことができるのではないでしょうか? – Zuriki

0

これはできません。それが可能であった場合は、これを考慮してください。

Beta beta = new Beta(); 
Alpha stillBeta = (Alpha)beta; // Here the compile-time type is Alpha, 
           // but the run-time type is Beta. 
AlphaArgs alphaArgs = new AlphaArgs(1,2); 
stillBeta.OnSpecialEvent(alphaArgs); // What should happen here? 

今すぐ BetaArgsを期待して、あなたの Betaインスタンスは、代わりに AlphaArgsの少ないから派生したインスタンスを取得しています。それはうまくいかない - それは多型を破る。

0

ジェネリック薬を使用できます。

public class Alpha<T> 
{ 
    protected virtual void OnSpecialEvent(T e) 
    { 
     //do stuff 
    } 
} 

は必ずジェネリック型TがAlphaArgsに制限されていることを確認するには、次のではなくAlphaArgsのジェネリック型を受け入れるよう

public interface IBase<T> 
    { 
     void OnSpecialEvent(T e); 
    } 

    public class Alpha : IBase<AlphaArgs> 
    { 
     public void OnSpecialEvent(AlphaArgs e) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public class Beta : IBase<BetaArgs> 
    { 
     public void OnSpecialEvent(BetaArgs e) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public class AlphaArgs 
    { 
     public int A { get; } 
     public object B { get; } 
    } 

    public class BetaArgs 
    { 
     public string C { get; } 
    } 
+0

申し訳ありませんが、私は明らかにすべきです、私は基本クラスをC#、この場合はBackgroundWorkerに組み込まれているように編集することはできません。 – Zuriki

0

あなたはOnSpecialEvent()を変更することでこれを実現することができます見てみましょうまたはそれを継承他のクラス(この場合はBetaArgs)、ジェネリック型の制約を追加します。

public class Alpha<T> where T : AlphaArgs 
{ 
    protected virtual void OnSpecialEvent(T e) 
    { 
     //do stuff 
    } 
} 

すると以下のようにベータ版を定義することによって、あなたは型を指定することができますBeta.OnSpecialEventに渡す引数の数。

public class Beta : Alpha<BetaArgs> 
{ 
    protected override void OnSpecialEvent(BetaArgs e) 
    { 
     //do stuff 
    } 
} 

(実際には、Visual Studio AutoCompleteはベータ版と同じ署名を提案します。OnSpecialEvent) Visual Studio AutoComplete on overridden function with a generic argument

全体のコードは次のようになります。一例では

public class AlphaArgs 
{ 
    public AlphaArgs(int a, object b) 
    { 
     //do stuff 
    } 

    public int A { get; } 
    public object B { get; } 
} 

public class BetaArgs : AlphaArgs 
{ 
    public BetaArgs(int a, object b, string c) : base(a, b) 
    { 
     /* Do Stuff */ 
    } 

    public string C { get; } 
} 

public class Alpha<T> where T : AlphaArgs 
{ 
    protected virtual void OnSpecialEvent(T e) 
    { 
     //do stuff 
    } 
} 

public class Beta : Alpha<BetaArgs> 
{ 
    protected override void OnSpecialEvent(BetaArgs e) 
    { 
     //do stuff 
    } 
} 
関連する問題