用户定义的结构转换作为函数的默认参数
本文关键字:函数 默认 参数 转换 定义 结构 用户 | 更新日期: 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;
}
它通过了!因此,我认为默认参数中允许类型转换。
所以我的问题是:
- 为什么不能使用 MyInt 的隐式类型转换作为默认段落?
- 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);
}