C# 隐式运算符 MyType(int value) 自动“支持”从浮点数转换

Posted

技术标签:

【中文标题】C# 隐式运算符 MyType(int value) 自动“支持”从浮点数转换【英文标题】:C# implicit operator MyType(int value) automatically "supports" cast from float 【发布时间】:2022-01-20 23:44:38 【问题描述】:

当我将转换运算符从 int 实现为我的类型时,它似乎“自动”支持从 float 进行转换。我不希望我的类型从浮点数隐式转换!我什至不希望它从 float 显式转换(从 float 定义显式转换还不够好)。

我可以防止这种行为吗? 是否有一些规范解释这一点?

原因: 我正在尝试学习/探索确定性定点数学,并且从浮点数中进行的强制转换通常是“危险区域”。 Int 强制转换很好,需要是隐式的。在需要浮点转换的情况下,我更喜欢静态方法来更好地指定意图,例如:MyNumber.ParseUnsafe(0.1f)

public struct MyNumber

    public int raw;

    public static implicit operator MyNumber(int x)
    
        return new MyNumber  raw = x * 10 ;
    


public static class Test

    public static void TestSomething()
    
        MyNumber num = (MyNumber)0.1f; // This must be compiler error, but it isn't!
    

【问题讨论】:

这一定是编译器错误 - 如果你使用不适合 int 的浮点数 【参考方案1】:

The language specification 说:

用户定义的显式转换包括一个可选的标准显式转换,然后执行用户定义的隐式或显式转换运算符,然后是另一个可选的标准显式转换。

所以floatMyNumber 的显式转换。它是一种“用户定义的显式转换”,包括从floatint 的转换(这是一种“标准显式转换”),然后执行隐式转换运算符。

This section explains this in more detail.

试图阻止这种情况的一个想法是尝试找到一个类型T,这样有一个从intT的standard explicit conversion,但不是从floatT,即也不会丢失信息。我想不出这种类型,而且我认为这不太可能存在:(

【讨论】:

以上是关于C# 隐式运算符 MyType(int value) 自动“支持”从浮点数转换的主要内容,如果未能解决你的问题,请参考以下文章

为啥“as”运算符在 C# 中不使用隐式转换运算符?

C# 隐式转换和 == 运算符

为啥 C# 编译器不调用隐式运算符。编译器错误?

Unity——C#数组

C#错误(无法将类型'string'隐式转换为'int')[重复]

在 C# 中将对象数组隐式转换为 int 数组