簡體   English   中英

C# - 更改覆蓋方法的參數類型

[英]C# - Change argument type of override method

我有一個繼承的類,我試圖將事件方法的參數類型更改為一個不同的類型,該類型也是一個繼承類。

原始類:

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,我沒有任何“問題”,但我丟失了比我想添加的額外參數。

有什么明顯的我遺漏了,我什至不知道我在找什么......

你可以使用泛型! 看一看:

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

您可以通過更改 OnSpecialEvent() 使其接受泛型類型而不是 AlphaArgs 來實現此目的:

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

為了確保泛型類型 T 僅限於 AlphaArgs 或任何其他繼承自它的類(在本例中為 BetaArgs),請添加泛型類型約束:

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

然后通過如下定義 Beta,您可以指定要傳遞給 Beta.OnSpecialEvent 的參數類型。

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

(事實上​​,Visual Studio AutoComplete 會為 Beta.OnSpecialEvent 建議完全相同的簽名) Visual Studio AutoComplete 使用泛型參數重寫函數

整個代碼如下所示:

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

每當您想覆蓋基類的方法時,您必須使用與基類中相同的簽名來覆蓋它。 而且你不是覆蓋方法而是重載。 但是,您可以執行以下操作:

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

希望這會幫助你。

你不能那樣做。 如果可能的話,考慮一下:

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?

現在你的Beta實例,它期待BetaArgs ,而是得到一個較少派生的AlphaArgs實例。 那行不通——它破壞了多態性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM