在 C# 中重载 = 运算符

Posted

技术标签:

【中文标题】在 C# 中重载 = 运算符【英文标题】:Overloading = operator in C# 【发布时间】:2012-10-20 22:16:06 【问题描述】:

好的,我知道这是不可能的,但这是制定问题标题的最佳方式。问题是,我正在尝试使用我自己的自定义类而不是浮点数(用于确定性模拟),并且我希望语法尽可能接近。所以,我当然希望能够写出类似

的东西
FixedPoint myNumber = 0.5f;

有可能吗?

【问题讨论】:

只是为了确保:您知道 C# 已经包含一个名为 decimal 的固定精度数据类型? @Heinzi:decimal 仍然是浮点类型。它只使用 128 位而不是 32/64 和十进制指数而不是二进制。 @Joren:当然,很抱歉,我试图简洁。我的意思是:“如果您使用自定义定点数据类型来避免通常与二进制浮点数据类型相关的舍入问题,您可以考虑改用 decimal,即能够准确地表示十进制浮点数。如果您已经考虑并拒绝了该选项,请忽略此评论。” @Heinzi 十进制应该比整数数学慢(我的定点本质上是)。 @golergka:啊,好吧,有道理! 【参考方案1】:

是的,如果这个类是由你编写的,则为 FixedPoint 创建一个隐式类型转换运算符。

class FixedPoint

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

如果读者/编码人员不清楚 double 可以转换为 FixedPoint,您也可以改用显式类型转换。然后你必须写:

FixedPoint fp = (FixedPoint) 3.5;

【讨论】:

想展示一个例子吗?因为文档清楚地表明“=”不是可重载的运算符。 好吧,它实际上不会重载= 运算符,它只会引入一个演员表。如果您将其定义为显式转换,您将拥有:FixedPoint myNumber = (FixedPoint) 0.5f;。一开始你仍然会有一个浮点数,但它会自动转换为 FixedPoint。请注意,这意味着浮点表示仍然存在舍入错误:您实际上无法读取 literal 0.1f,您仍然会收到一个最能代表二进制的浮点数重复数字 0.1 作为重载方法的参数。 @Marc-AndréJutras 重载 = 是不可能的,这不是重载 :) @Marc-AndréJutras 什么?它不是这么说的。 @Marc-AndréJutras - 在这种情况下,Fero 不建议重载 = 运算符。 Fero 的建议是他们处理将 FixedPoint 转换为另一种类型。【参考方案2】:

重载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;

【讨论】:

第二个隐式运算符也是一个很好的补充!谢谢。【参考方案3】:

创建一个隐式类型转换。

这是一个例子:

<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>;

【讨论】:

【参考方案4】:

如果在 = 重载中隐式不是您想要的,另一种选择是在您的类上使用显式运算符,如下所示,它将强制转换为它,使其被用户理解:

public static explicit operator FixedPoint(float oc)     
         

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


... usage

FixedPoint myNumber = (FixedPoint)0.5f;

【讨论】:

以上是关于在 C# 中重载 = 运算符的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中是不是可以通过以下方式重载泛型强制转换运算符?

了解下C# 运算符重载

操作数的顺序对于 C# 中重载的 == 运算符是不是重要

C#中的运算符重载

C# 类型运算符重载在类继承中的调用测试

如何在 C# 中为枚举重载运算符?