隐式转换如何与运算符重载一起使用?
How do implicit conversions work with operator overloading?
比如说,如果我出于某种原因在浮点类型周围创建一个薄包装器,就像这样:
public class WrappedFloat
{
private float value;
public WrappedFloat(float value)
{
this.value = value;
}
public static implicit operator float(WrappedFloat wrapped)
{
return wrapped.value;
}
public static implicit operator WrappedFloat(float value)
{
return new WrappedFloat(value);
}
}
此代码显然完全有效:
new WrappedFloat(4.0F) + new WrappedFloat(3.0F)
因为 WrappedFloat
没有定义任何算术运算符,所以一定有一些关于它到 float
的隐式转换允许这样做。但是运算符重载只是方法的语法糖,对吧?这不像我可以在 WrappedFloat
上调用方法(即 CompareTo
)只是因为 float
有它们。那么这里的运算符有什么特别之处呢?允许这样做的规则是什么?
就本次讨论而言,运算符就像静态方法一样。想象一下,每个运算符重载都有一个实际的静态方法:
public static int Plus(int a, int b) { return a + b; }
public static float Plus(float a, float b) { return a + b; }
public static long Plus(long a, long b) { return a + b; }
public static string Plus(string a, string b) { return a + b; }
public static double Plus(double a, double b) { return a + b; }
//...
现在假设您有:
Plus(new WrappedFloat(4.0F), new WrappedFloat(3.0F));
您希望这里发生什么?重载解析会 运行,它会发现有一个重载,其两个参数都有一个隐式转换,并且该重载(接受 float
值)成为唯一的最佳匹配。
运算符也会发生完全相同的事情。它将所有重载放在一起,查看哪些重载具有可以隐式转换为所提供参数的参数列表,如果有多个重载,则从中选择最佳匹配。
But operator overloading is just syntactic sugar for methods, right?
它不是"methods"的语法糖,它是一种以特定方式实现的方法的语法糖。使用 .
语法对对象的典型方法调用在这里不适用。 MS 选择了一种方便程序员的设计。当我打电话时
wrappedFloat.Method()
我不希望它在 wrappedFloat
上寻找所有可能性,但是当我这样做时
wrappedFloat1 + wrappedFloat2
我希望如此。我在这里同意 MS。这里的一个区别是,第一种情况是对实例的调用,第二种是静态方法调用,其中形式参数作为参数传递。
比如说,如果我出于某种原因在浮点类型周围创建一个薄包装器,就像这样:
public class WrappedFloat
{
private float value;
public WrappedFloat(float value)
{
this.value = value;
}
public static implicit operator float(WrappedFloat wrapped)
{
return wrapped.value;
}
public static implicit operator WrappedFloat(float value)
{
return new WrappedFloat(value);
}
}
此代码显然完全有效:
new WrappedFloat(4.0F) + new WrappedFloat(3.0F)
因为 WrappedFloat
没有定义任何算术运算符,所以一定有一些关于它到 float
的隐式转换允许这样做。但是运算符重载只是方法的语法糖,对吧?这不像我可以在 WrappedFloat
上调用方法(即 CompareTo
)只是因为 float
有它们。那么这里的运算符有什么特别之处呢?允许这样做的规则是什么?
就本次讨论而言,运算符就像静态方法一样。想象一下,每个运算符重载都有一个实际的静态方法:
public static int Plus(int a, int b) { return a + b; }
public static float Plus(float a, float b) { return a + b; }
public static long Plus(long a, long b) { return a + b; }
public static string Plus(string a, string b) { return a + b; }
public static double Plus(double a, double b) { return a + b; }
//...
现在假设您有:
Plus(new WrappedFloat(4.0F), new WrappedFloat(3.0F));
您希望这里发生什么?重载解析会 运行,它会发现有一个重载,其两个参数都有一个隐式转换,并且该重载(接受 float
值)成为唯一的最佳匹配。
运算符也会发生完全相同的事情。它将所有重载放在一起,查看哪些重载具有可以隐式转换为所提供参数的参数列表,如果有多个重载,则从中选择最佳匹配。
But operator overloading is just syntactic sugar for methods, right?
它不是"methods"的语法糖,它是一种以特定方式实现的方法的语法糖。使用 .
语法对对象的典型方法调用在这里不适用。 MS 选择了一种方便程序员的设计。当我打电话时
wrappedFloat.Method()
我不希望它在 wrappedFloat
上寻找所有可能性,但是当我这样做时
wrappedFloat1 + wrappedFloat2
我希望如此。我在这里同意 MS。这里的一个区别是,第一种情况是对实例的调用,第二种是静态方法调用,其中形式参数作为参数传递。