开发者

How can I set default parameter value to BigInteger type?

I need to have a class that has a constructor with BigInteger type. I'd like to set a default value to 0 to it with this code, but I got compile error.

public class 开发者_JAVA百科Hello
{
    BigInteger X {get; set;}
    public Hello(BigInteger x = 0)
    {
        X = x;
    }
}

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

What's wrong? Is there way to set default value to BigInteger parameter?


Default parameters only work compile time constants (and value types where the parameter can be default(ValType) or new ValType()), and as such don't work for BigInteger. For your case, you could perhaps do something like this; providing a constructor overload that takes int, and make that have a default parameter:

public Hello(int x = 0) : this(new BigInteger(x)) {}
public Hello(BigInteger x) 
{
    X = x;
}

In case you are wondering, the x = 0 doesn't count as a constant when the type is a BigInteger, because converting 0 to BigInteger would involve invoking the implicit conversion operator for int to BigInteger.


In this particular case, since the default value you want is zero, you can use the default BigInteger constructor because BigInteger is a value type:

public class Hello
{
    BigInteger X { get; set; }

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

This will not work with values besides zero because the expression must be a compile time constant:

Each optional parameter has a default value as part of its definition. If no argument is sent for that parameter, the default value is used. A default value must be one of the following types of expressions:

  • a constant expression;
  • an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
  • an expression of the form default(ValType), where ValType is a value type.


Use an overloaded constructor

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


From §10.6.1 of the C# 4 spec:

The expression in a default-argument must be one of the following:

  • a constant-expression
  • an expression of the form new S() where S is a value type
  • an expression of the form default(S) where S is a value type

The expression must be implicitly convertible by an identity or nullable conversion to the type of the parameter.

What this means for BigInteger is that the only option for default argument is to use 0, expressed either as new BigInteger() or default(BigInteger).

BigInteger x = 0 doesn't work, because 0 is of type int and the implicit conversion from int to BigInteger is not “an identity or nullable conversion”.

If you want the default argument to be anything else other than 0, you have several options:

  • use BigInteger?, let the default be null and at the beginning of the method check for that. If the parameter is null, set it to the default value.
  • create another overload of the method that takes e.g. int with the default argument specified. This method in turn calls the BigInteger overload that doesn't have the default argument. This assumes the default value fits in an int, but I think that should be the case most of the time.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜