2016-03-19 16 views
-1

Ich habe eine geerbte Klasse und ich versuche, den Argumenttyp der Ereignismethode in einen anderen Typ zu ändern, der auch eine geerbte Klasse ist.C# - Ändern des Argumenttyps der Überschreibungsmethode

Die ursprünglichen Klassen:

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; } 
} 

Meine inheriting Klassen:

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; } 
} 

Aber ich mit dem Fehler am Ende:

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

Wenn ich AlphaArgs verwenden Ich habe keine jedes 'Problem', aber ich verliere den zusätzlichen Parameter, als ich hinzufügen möchte.

Gibt es etwas offensichtlich fehlt mir, ich weiß nicht einmal, was ich suche ...

Antwort

0

, wenn Sie eine Methode der Basisklasse außer Kraft setzen möchten, müssen Sie es außer Kraft setzen müssen, um mit die gleiche Signatur wie in der Basisklasse. Außerdem überschreiben Sie die Methode nicht, sondern überladen sie. Sie können jedoch wie folgt vorgehen:

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

oder wenn Sie möchten, können Sie eine Überlastung OnSpecialEvent erstellen.

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

für weitere Informationen, können Sie dies hier lesen. https://stackoverflow.com/a/27547235/1926877

Hoffe, das wird Ihnen helfen.

+0

In Beispiel eins: Ich würde den BetaArgs Parameter nicht in der Lage sein passieren OnSpecialEvent weil BetaArgs weiter unten in der Vererbungskette ist, nicht wahr? – Zuriki

0

Sie können das nicht tun. Wenn es möglich war, bedenken Sie:

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? 

nun Ihre Beta Instanz, die BetaArgs erwartet wird, stattdessen wird immer eine weniger abgeleitete Instanz von AlphaArgs. Das kann nicht funktionieren - es bricht den Polymorphismus.

0

Sie können Generika verwenden! Werfen Sie einen Blick:

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

Entschuldigung, ich hätte klar sein sollen, ich kann die Basisklassen nicht bearbeiten, da sie in C# eingebaut sind, in diesem Fall BackgroundWorker. – Zuriki

0

Sie können dies erreichen, indem OnSpecialEvent Wechsel(), so dass es statt AlphaArgs einen generischen Typen akzeptiert:

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

Um sicherzustellen, dass die generische Typ T auf AlphaArgs beschränkt ist oder jede andere Klasse von ihm (BetaArgs in diesem Fall) zu erben, fügen Sie eine generische Typeinschränkung:

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

dann von Beta zu definieren, wie unten Sie den Typ angeben des Arguments, das an Beta.OnSpecialEvent übergeben werden soll.

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

(In der Tat schlägt Visual Studio AutoComplete exakt die gleiche Signatur für Beta vor.OnSpecialEvent) Visual Studio AutoComplete on overridden function with a generic argument

Der gesamte Code würde wie folgt aussehen:

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 
    } 
}