-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overload resolution of virtual methods is overly restrictive #1502
Comments
We need to bear in mind that implicit conversions need to be accounted for. In the C# standard they are sufficient to match a derived overload against arguments, and thus supersede the override, even if override is exact type match. Example with implicit conversion: class C
{
public virtual float P(float v) => v;
}
class D : C
{
public override float P(float v) => v;
public double P(double v) => v;
}
var d = new D();
// the following call will use the double overload in the derived class
// even though override is exact type match with float type!
// this is because float has implicit conversion to double
d.P(5F); Counterposed example with explicit conversion: class E
{
public virtual float P(float v) => v;
}
class F : E
{
public override float P(float v) => v;
public decimal P(decimal v) => v;
}
var f = new F();
// the following call will match the float overload in the derived class
// because there is no implicit conversion to decimal (although there is an explicit one!)
f.P(5F); Note P.S.: Actually this argument does not apply for the most part since all workflow method signatures are generic type interfaces (i.e. |
Following #1452 the following workflow will not compile with a "method overload resolution is ambiguous" error:
Workflow
This happens because of the specific overloads declared in
UpdateAudioState
sink combined with the current overload resolution strategy where the compiler will accept matches to overloads where input types can be coerced:The base generic method is thus excluded and, since both of the other two matching overloads are supported on an explicit user conversion from the
object
type (hence leaving no preferential conversion that can be used as tie-break), overload resolution is left ambiguous.The above example illustrates that signature resolution matching rules in the current compiler are too permissive. Matching signatures from more derived types should indeed exclude matching base type signatures, but this should not work for overloads which are matched based only on explicit conversions, as this violates C# overload resolution rules.
In fact, even implicit conversions between types are probably too permissive. Likely the only implicit conversion rules that should be allowed here are the rules for variance in generic interfaces, which allow generic interfaces with more derived type parameters to match against generic interfaces with a less derived type. Variance in generic interfaces is only supported for reference types, so conversions between value type sequences should not be considered for the purposes of excluding virtual overloads in combinators.
Reference:
The text was updated successfully, but these errors were encountered: