用户定义的结构转换作为函数的默认参数

本文关键字:函数 默认 参数 转换 定义 结构 用户 | 更新日期: 2023-09-27 18:31:21

public struct MyInt
{
    public int csInt;
    public MyInt(int i)
    {
        csInt = i;
    }
    public MyInt(double d)
    {
        csInt = (int)d;
    }
    public static implicit operator MyInt(int value)
    {
        return new MyInt(value);
    }
    public static implicit operator MyInt(double value)
    {
        return new MyInt(value);
    }
}

int MyFunc(MyInt i = 0)
{
    return -1;
}

我想实现一个包装结构MyInt(此处简化)以接受int作为默认值(我知道这很奇怪和不自然,我只需要它来符合其他语言格式),但是当我像上面这样编码时我遇到了错误,错误在VS2012说的int MyFunc(MyInt i = 0)

类型为"int"的值不能用作默认参数,因为没有对 MyInt 类型的标准转换

据我所知,int 和 double 在 C# 中也被定义为结构体。所以我尝试了以下方法:

int MyFunc(double i = (int)0)
{
return -1;
}

它通过了!因此,我认为默认参数中允许类型转换。

所以我的问题是:

  1. 为什么不能使用 MyInt 的隐式类型转换作为默认段落?
  2. VS 错误消息中的标准转换是什么意思,它与 MyInt 中定义的隐式转换有什么不同吗?

用户定义的结构转换作为函数的默认参数

隐式转换运算符是方法,您不能使用方法(或事件静态字段)作为默认参数 - 只允许使用常量(这是有意义的,因为编译器实际上会在您调用该方法的任何地方使用这些常量

在您的情况下,由于您想要结构的默认值(即所有字段初始化为 0),您可以使用 default 关键字:

int MyFunc(MyInt i = default(MyInt))
{
    return -1;
}

C# 标准转换是编译器可以自行执行的转换(如 Int32 到 Double 或任何类型的 Object 转换)。可以在 C# 规范中阅读有关它们的所有信息。

如果你试试这个:

int MyFunc(MyInt i = (MyInt)0)

您收到错误

"i"的默认参数值必须是编译时常量

这告诉你为什么它不能工作 - 在编译时,没有办法告诉你如何转换你键入到MyInt中的0(因为你的运算符代码在运行时运行)。

它适用于double,因为 C# 编译器知道该类型;它不是用户定义的。

可以通过定义重载而不是使用默认参数值来解决此问题:

int MyFunc(MyInt i)
{
    return -1;
}
int MyFunc()
{
    return MyFunc((MyInt)0);
}