【问题标题】:How to make a derived method, which takes different arguments than overriden function in C#?如何制作一个派生方法,它采用与 C# 中的覆盖函数不同的参数?
【发布时间】:2012-04-16 20:17:12
【问题描述】:

我有一堂课,是这样的:

class BaseClass
{
  protected int X;
  virtual void ChangeParameters(int NewX)
  {
    this.X = newX;
  }
}

class DerivedClass1 : BaseClass
{
  private int a;
  private int b;
}

class DerivedClass2 : BaseClass
{
  private int a;
}

当我想在派生类中重写 ChangeParameters() 函数时,问题就来了,因为它们中的每一个都可以有不同数量的参数。

那么问题来了——我怎样才能创建一个虚函数,它可以在派生类中改变参数数量?

PS。我不想使用 params 关键字,因为我更希望类的用户确切地知道他必须将多少参数传递给函数。

【问题讨论】:

标签: c#


【解决方案1】:

你不能。如果是override,则签名必须完全匹配。如果你想要不同的参数,它听起来不像override - 毕竟......调用者如何调用它,只知道基本类型? (替代校长等)

BaseClass obj = GetSomeConcreteObject(); // actually a DerievedClass2
obj.ChangeParameters({what would go here?});

在我看来,这些只是独立的方法。你可以有一个virtual方法接受一个数组(有或没有params),但是你需要接受调用者可以提供任何大小。

【讨论】:

    【解决方案2】:

    这是不可能的。

    根据定义,覆盖必须保持与原始方法相同的名称和参数集(也称为签名)。

    如果您使用不同的参数,运行时应该如何将您的“覆盖”绑定到超类上的方法调用?想象一下这是可能的:

    class A
    {
        virtual void Foo(int i) { Console.WriteLine(i); }
    }
    
    class B : A
    {
        override void Foo(int i, int j) { Console.WriteLine(i + j); }
    }
    
    // somewhere else
    
    void DoSomething(A a)
    {
        a.Foo(1);
    }
    
    // later
    
    DoSomething(new B()); // how will b.Foo get called inside DoSomething?
    

    如果你改变参数,你得到的只是过载。

    【讨论】:

      【解决方案3】:

      也可以使用可选参数来完成有趣的技巧,如下所示:

      public class Base
      {
           public virtual void DoSomething(string param="Hello", string param1 = "Bye") 
           {
      
          Console.WriteLine(string.Format("prm: {0}, prm1: {1}", param, param1));
           }
      }
      
      public class Derived  : Base
      {
          public override void  DoSomething(string param="Ciao", string param1="Ciao")
          {
                Console.WriteLine(string.Format("prm: {0}, prm1: {1}", param, param1));
          }
      }
      

      所以你可以在如下代码中使用:

      Base a = new Derived();
      a.DoSomething();
      

      输出是:

      prm: Hello, prm1: Bye
      

      但你现在可以这样做:

      Base a = new Derived();
      a.DoSomething("Ciao");
      

      输出如下:

      prm: Ciao, prm1: Bye //!! 
      

      【讨论】:

        猜你喜欢
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2021-06-14
        • 2014-01-15
        • 2018-12-23
        • 1970-01-01
        相关资源
        最近更新 更多