C#Ambiguous函数重载 - 矩形与rectanglef

时间:2015-10-28 11:04:51

标签: c# ambiguous

我有一行代码

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)'

显然这是正确的,因为有超负荷。如何指定我想使用Rectangle?

1 个答案:

答案 0 :(得分:4)

此处的错误消息非常容易引起误解。这两个重载之间的调用实际上是模糊的:

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#中的重载解析过程在C#语言规范的7.5.3节中描述。

第一步是创建一组适用的功能成员。基本上(忽略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参数的方法,因为身份转换优于隐式转换。

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