C# - 更改覆盖方法的参数类型

时间:2016-03-19 11:20:49

标签: c# .net-2.0

我有一个继承的类,我正在尝试将事件方法的参数类型更改为另一个也是继承类的类型。

原始课程:

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,我就不会遇到任何问题'但是我失去了额外的参数而不是我想要添加的。

有什么明显的东西我不知道,我甚至都不知道我在寻找什么...

4 个答案:

答案 0 :(得分: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

希望这会对你有所帮助。

答案 1 :(得分: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?

现在,期待Beta的{​​{1}}实例正在获取BetaArgs的较少派生的实例。这无法奏效 - 它打破了多态性。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

您可以通过更改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 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
    }
}