【问题标题】:C# - Change argument type of override methodC# - 更改覆盖方法的参数类型
【发布时间】:2016-03-19 11:20:49
【问题描述】:

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

原来的类:

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,我没有任何“问题”,但我会丢失我想要添加的额外参数。

有什么明显的我错过了,我什至不知道我在寻找什么......

【问题讨论】:

    标签: c# .net-2.0


    【解决方案1】:

    你可以使用泛型!看看:

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

    【讨论】:

    • 抱歉,我应该很清楚,我无法编辑基类,因为它们内置于 C# 中,在本例中为 BackgroundWorker。
    • 但就我而言,这就是我正在寻找的答案。谢谢!
    【解决方案2】:

    您可以通过更改 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 建议相同的签名)

    整个代码如下所示:

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

    【讨论】:

      【解决方案3】:

      无论何时你想重写基类的方法,你必须用与基类相同的签名来重写它。而且你不是覆盖方法而是重载。但是,您可以执行以下操作:

      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

      希望这会对你有所帮助。

      【讨论】:

      • 在示例一中:我无法将 BetaArgs 参数传递给 OnSpecialEvent,因为 BetaArgs 在继承链的下游,不是吗?
      【解决方案4】:

      你不能那样做。如果可能的话,考虑一下:

      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 实例。这是行不通的——它破坏了多态性。

      【讨论】:

        猜你喜欢
        • 2021-11-16
        • 2012-12-21
        • 1970-01-01
        • 2013-08-22
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多