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()
whereS
is a value type- an expression of the form
default(S)
whereS
is a value typeThe 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 benull
and at the beginning of the method check for that. If the parameter isnull
, 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 theBigInteger
overload that doesn't have the default argument. This assumes the default value fits in anint
, but I think that should be the case most of the time.
精彩评论