用户定义的struct转换为函数的默认参数

时间:2013-09-16 04:12:04

标签: c# casting default-parameters

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作为默认值(我知道这很奇怪且不自然,我只需要它遵守其他语言格式),但是我在上面编码时遇到错误,错误发生在int MyFunc(MyInt i = 0),VS2012说:

  

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

据我所知,int和double也在C#中定义为struct。所以我试过以下:

int MyFunc(double i = (int)0)
{
return -1;
}
它通过了!因此我认为默认参数允许类型转换。

所以我的问题是:

  1. 为什么不能将MyInt的隐式类型转换用作默认的para?
  2. 标准转换在VS错误消息中的含义是什么,它是否来自MyInt中定义的隐式转换?

2 个答案:

答案 0 :(得分:1)

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

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

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

C#标准转换是编译器可以自己执行的转换(如Int32到Double或任何类型到Object)。您可以在C# Specification

中阅读有关它们的所有信息

答案 1 :(得分:0)

如果您尝试这样做:

int MyFunc(MyInt i = (MyInt)0)

您收到错误

  

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

它告诉你它无法工作的原因 - 在编译时,没有办法告诉你如何将你输入的0转换为MyInt(因为你的运算符代码在运行时运行 - 时间)。

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

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

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

int MyFunc()
{
    return MyFunc((MyInt)0);
}