如何将默认参数值设置为 BigInteger 类型?

4

我需要一个具有BigInteger类型构造函数的类。 我想用以下代码将默认值设置为0,但是我得到了编译错误。

public class Hello
{
    BigInteger X {get; set;}
    public Hello(BigInteger x = 0)
    {
        X = x;
    }
}

public class MyClass
{
    public static void RunSnippet()
    {
        var h = new Hello(); // Error <-- 

出了什么问题吗?有没有办法为 BigInteger 参数设置默认值?

4个回答

6
默认参数仅适用于编译时常量(和值类型,其中参数可以是default(ValType)new ValType()),因此不适用于BigInteger。针对您的情况,您可以尝试像这样做; 提供一个接受int的构造函数重载,并使其具有默认参数:
public Hello(int x = 0) : this(new BigInteger(x)) {}
public Hello(BigInteger x) 
{
    X = x;
}

如果你有疑问,当类型为BigInteger时,x = 0不被视为常量,因为将0转换为BigInteger涉及调用int到BigInteger的隐式转换运算符

默认参数不仅适用于整型。你可以像这样做:string s = null - svick

3
在这种情况下,由于您想要的默认值是零,因此可以使用默认的 BigInteger 构造函数,因为 BigInteger 是一个值类型。
public class Hello
{
    BigInteger X { get; set; }

    public Hello(BigInteger x = new BigInteger())
    {
        X = x;
    }
}

这不适用于非零值,因为表达式必须是编译时常量

每个可选参数都有一个默认值作为其定义的一部分。如果没有为该参数发送参数,则使用默认值。默认值必须是以下类型之一的表达式:

  • 常量表达式;
  • 形如new ValType()的表达式,其中ValType是值类型,例如枚举或结构体;
  • 形如default(ValType)的表达式,其中ValType是值类型。

但是像 42 这样的值确实是编译时常量。 - svick
@svick:但不幸的是,42无法转换为BigInteger,因此它是一个编译时常量,但出于不同的原因是非法的。 - Rick Sladkey
但是 42 可以转换为 BigIntegerintBigInteger 存在隐式转换。 - svick
你是正确的。错误信息实际上是:“int”类型的值不能用作默认参数,因为没有标准转换到“System.Numerics.BigInteger”类型(重点添加)。 - Rick Sladkey

2

使用重载构造函数

public class Hello
{
    BigInteger X {get; set;}
    public Hello(BigInteger x)
    {
        X = x;
    }
    public Hello()
    {
        X = new BigInteger(0);
    }
}

0

来自C# 4规范的§10.6.1:

默认参数中的表达式必须是以下之一:

  • 常量表达式
  • 形如new S()的表达式,其中S是值类型
  • 形如default(S)的表达式,其中S是值类型

表达式必须通过身份或可空转换隐式转换为参数的类型。

对于BigInteger而言,这意味着默认参数的唯一选项是使用0,可以表示为new BigInteger()default(BigInteger)

BigInteger x = 0不起作用,因为0int类型,从intBigInteger的隐式转换不是“身份或可空转换”。

如果您希望默认参数为除0以外的任何其他内容,则有几个选项:

  • 使用 BigInteger?,让默认值为 null 并在方法开头检查。如果参数是 null,则将其设置为默认值。
  • 创建另一个重载方法,例如使用指定的默认参数 int。该方法调用没有默认参数的 BigInteger 重载方法。这假设默认值适合于 int,但我认为大多数情况下都是这样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接