3

I have two overloaded methods, one with params and one without. If I call that method without specifying any params, it hits the one with params all the same.

Take the following example:

public abstract class A<T>
{
  public virtual T Get(int idEntity)
  {
    return this.DefaultRepository.Get(idEntity);
  }
}

public class B<T> : A<T>
{
  public override T Get(int idEntity)
  {
    this.DoSomeValidation();
    var t = this.GetTheEntity();
    return t;
  }

  public T Get(int idEntity, params sbyte[] AccessModifiers)
  {
    this.DoOtherValidations(AccessModifiers);
    var t = this.GetTheEntity();
    return t;
  }
}

If I do this in another class:

public class SomeClass
{
  public void SomeMethod(int idT)
  {
    var x = new B();
    var t = B.Get(idT);
  }
}

Then the method public T Get(int idEntity, params sbyte[] AccessModifiers) is called, instead of public override T Get(int idEntity). I was expecting the latter to be called, it being more specific than the former, since I didn't specify any "params". Why is that? Thanks a lot.

Pona
  • 167
  • 1
  • 17
  • 2
    Your code doesn't compile. Your `class B : A` requires a type argument for `A`. If you have a separate non-generic class `A` then that might be part of the problem. – Dai Jan 06 '20 at 14:19
  • I'm fairly sure the answer is "because it's a "first-class" member of type `B`" and the overridden one is not, but I'd have to read through the specification to verify.. – Ron Beyer Jan 06 '20 at 14:20
  • @RonBeyer When I run it in LinqPad with `B` as `this`, then it calls the `params` version - when I change it to a virtual call from `A` as `this` then it calls the non-params method - so you're right. – Dai Jan 06 '20 at 14:22
  • So in conclusion, an empty params array is considered more specific than a virtual method without params. – Holger Jan 06 '20 at 14:30
  • @PavelAnikhouski The issue was, the params version is called, you confirm the issue. We look for the specification explaining the behaviour. – Holger Jan 06 '20 at 14:31
  • 1
    Obviously both methods match that signature, so the one from `B` is chosen rather than the base method. You can use `((A)(new B())).Get(1);` to call the other method. if it wasn't an `override` then the `params`less one would be chosen first. – Bizhan Jan 06 '20 at 14:31
  • I get the reason now, thanks to @Bizhan, though it's kinda confusing. In our case, we own both assemblies, so we can look at the code, but I imagine it would be a huge headache if it happenned with an external assembly. – Pona Jan 06 '20 at 15:40

0 Answers0