在C#中重载等号运算符

17

好的,我知道这是不可能的,但这是提出问题标题的最佳方式。问题是,我想使用自己的自定义类而不是float(用于确定性模拟),并且我希望语法尽可能接近。因此,我肯定希望能够编写类似以下的内容:

FixedPoint myNumber = 0.5f;

可能吗?


只是为了确认:您知道 C# 已经包含一个名为 decimal 的定点数据类型吗? - Heinzi
@Heinzi:decimal仍然是一种浮点类型。它只是使用128位而不是32/64位,并且使用十进制指数而不是二进制指数。 - Joren
1
@Joren:当然,抱歉,我试图简洁明了。我本意想写的是:“如果您正在使用自定义的定点数据类型来避免通常与二进制浮点数据类型相关联的舍入问题,您可以考虑改用十进制,它能够准确地表示十进制浮点数。如果您已经考虑并拒绝了该选项,请忽略此评论。” - Heinzi
@Heinzi,十进制运算应该比整数运算慢(而我的定点运算本质上就是整数运算)。 - Max Yankov
4个回答

33

如果您编写了这个类,那么可以通过为FixedPoint创建一个隐式类型转换运算符来实现。

class FixedPoint
{
    public static implicit operator FixedPoint(double d)
    {
        return new FixedPoint(d);
    }
}

如果读者/编码人员不明显知道一个 double 可以转换为 FixedPoint,您也可以使用显式类型转换。此时您需要编写:

如果读者/编码人员不明显知道一个 double 可以转换为 FixedPoint,您也可以使用显式类型转换。此时您需要编写:

FixedPoint fp = (FixedPoint) 3.5;

你能展示一个例子吗?因为文档明确说明“=”是不可重载的运算符。 - LightStriker
3
实际上,这并不会使=操作符超载,它只会引入一个类型转换。如果您定义为显式强制类型转换,则会有:FixedPoint myNumber = (FixedPoint) 0.5f;。一开始仍然是一个浮点数,但它将被自动转换为FixedPoint类型。请注意,这意味着您仍然会受到来自浮点数表示的舍入误差:您实际上无法读取文字 0.1f,您将收到最能表示二进制重复数字0.1的浮点数作为重载方法的参数。 - Mattias Buelens
@Marc-AndréJutras 重载 = 是不可能的,这不是重载 :) - Jon B
@Marc-AndréJutras - Fero并不建议在这种情况下重载=运算符。Fero建议的是处理将FixedPoint转换为另一种类型的操作。 - Security Hound
@golergka Cuong Le的回答也有一个很好的观点,拥有目标类型的内在转换对通常非常有用。 - asawyer
显示剩余4条评论

8

重载 implicit 转换运算符:

class FixedPoint
{
    private readonly float _floatField;

    public FixedPoint(float field)
    {
        _floatField = field;
    }

    public static implicit operator FixedPoint(float f)
    {
        return new FixedPoint(f);
    }

    public static implicit  operator float(FixedPoint fp)
    {
        return fp._floatField;
    }
}

所以你可以使用以下内容:
FixedPoint fp = 1;
float f = fp;

2
第二个隐式操作符也是一个很棒的补充!谢谢。 - Max Yankov

1

创建一个隐式类型转换。

这是一个例子:

<class> instance = new <class>();

float f = instance; // We want to cast instance to float.

public static implicit operator <Predefined Data type> (<Class> instance)
{
    //implicit cast logic
    return <Predefined Data type>;
}

1
如果隐式转换不是你在重载中想要的,另一个选择是在你的类上使用显式操作符,如下所示,它将强制转换为它,使用户理解:
public static explicit operator FixedPoint(float oc)     
{         

     FixedPoint etc = new FixedPoint();          
     etc._myValue = oc;          
     return etc;      
}

... usage

FixedPoint myNumber = (FixedPoint)0.5f;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接