C#模糊函数重载-矩形与矩形

本文关键字:重载 模糊 函数 | 更新日期: 2023-09-27 18:19:39

我有一行代码

System.Drawing.Drawing2D.LinearGradientBrush gradient = new System.Drawing.Drawing2D.LinearGradientBrush(new System.Drawing.Rectangle(5, 5, 100, 100), Color.Red, Color.Green, 0);

这抛出了一个错误

The call is ambiguous between the following methods or properties: 'LinearGradientBrush.LinearGradientBrush(RectangleF, Color, Color, LinearGradientMode)' and 'LinearGradientBrush.LinearGradientBrush(Rectangle, Color, Color, LinearGradientMode)'

显然,这是正确的,因为有过载。如何指定要使用矩形?

C#模糊函数重载-矩形与矩形

这里的错误消息非常具有误导性。这两个重载之间的调用实际上是不明确的:

public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle);
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode);

问题是您试图将最后一个参数作为int而不是LinearGradientMode传递。如果您传递LinearGradientMode枚举的值,它将编译:

gradient = new LinearGradientBrush(
                 new Rectangle(5, 5, 100, 100), 
                 Color.Red, 
                 Color.Green, 
                 LinearGradientMode.Horizontal);

编辑

一些解释为什么错误消息在这种情况下如此误导:

C#语言规范的第7.5.3节描述了C#中过载解决的过程。

第一步是创建一组适用的功能成员。基本上(忽略params和可选参数),这些方法都具有与调用中指定的相同数量的参数,并且从每个参数到相应参数的类型都有一个隐式转换。

传递的参数有4个适用的构造函数LinearGradientBrush

public LinearGradientBrush(RectangleF rect, Color color1, Color color2, LinearGradientMode linearGradientMode);
public LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle);
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle);
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode);

因为:

  • 存在从RectangleRectangleF的隐式转换(第一个参数)
  • 存在从intfloat的隐式转换(最后一个参数)
  • 存在从0到任何enum类型的隐式转换(最后一个参数)

从这个列表中,编译器试图找到要调用的最佳成员。如果失败,它将报告一个错误。错误消息仅包含适用成员列表中的2个方法的签名。

如果我们想使用第7.5.3.2节中描述的规则对这些成员进行排序,我们将获得

1. public LinearGradientBrush(Rectangle, Color, Color, float);
1. public LinearGradientBrush(Rectangle, Color, Color, LinearGradientMode);
3. public LinearGradientBrush(RectangleF, Color, Color, float);
3. public LinearGradientBrush(RectangleF, Color, Color, LinearGradientMode); 

采用Rectangle参数的方法比采用RectangleF参数的方法好,因为恒等式转换比隐式转换好。

然而,编译器并不是这样做的。编译器只查找一个最佳成员。如果找不到它,它会报告一个错误。错误消息基于整个适用的成员列表,并且可以包含该列表中的任何方法签名。