The C # compiler is giving incorrect arguments. What for?
I have a class that contains two methods like this:
public String getFoo(Int32 a)
{
return getBar(a, "b", null);
}
public String getBar(Int32 a, String b, Int32 c)
{
//do something
return "";
}
However, when I compile my class, I get two errors:
- Best overloaded method match for getBar (int, string, int) has some invalid arguments
- Argument '3': cannot convert from '
<null>
' to 'int'
I think I understand why I am getting this error: the compiler does not know at compile time what the real type of the object is. Can anyone confirm if I am the correct reason for the cause of the error or indicate the real reason?
More importantly, can I create my code this way? If so, what should I do to correct the errors? My reason for designing my class this way is because I don't want to duplicate code in getBar, in getFoo. These two methods do the same thing, except one takes a third parameter.
Thank.
source to share
In .NET, there is a clear concept between reference types and value types.
The reference type is an object allocated on the heap (this will be a subclass of System.Object). Everything on the stack is a pointer to this object. Because of this, it is perfectly acceptable to store a null pointer.
The value type is an object allocated on the stack, it will subclass System.ValueType. Since the value type lives on the stack, when you pass its value to a function, you are passing the entire contents of the object.
Value types cannot be empty.
Most of the primitive types in C # are value types. String is a special type of primitive that is actually a reference type.
In .NET 2.0, MS added the ability to wrap a generic type inside a struct so that it can model a nullable type. What's really going on is that the logic inside the Nullable <T> struct emulates null for you.
They expressed this using a syntax shortcut by adding a question mark to the type, for example:
int? nullableInt = null;
float? nullableFloat = null;
etc...
If you don't like int? syntax, you can always use Nullable <SomeType>
public String getBar(Int32 a, String b, Nullable<Int32> c)
As a side note, I prefer to add overloading when doing what you are doing to make the syntax nicer.
public String getBar(Int32 a, String b)
{
this.getBar(a,b,null);
}
public String getBar(Int32 a, String b, Nullable<Int32> c)
{
}
source to share
Int32 is an alias for int, which is of type value / non-nullable. For the null version, use System.Nullable or just "int?"
Also, don't forget to cast back to a non-nullable int:
int? nullable = ...;
int non_nullable = nullable??0;
where the number indicates what value it should take if it is indeed null.
source to share
Sunny is correct.
Int32 is a value type and cannot contain null. If you need to pass "null" as the parameter value, use Nullable instead of Int32 as your argument type.
More information can be found in Nullable Types (C # Programming Guide) on MSDN.
source to share
Ok so fiveseven people suggested int?
as a solution. I suggest two other solutions that might be more appropriate depending on the situation;
-
Create a method overload that has only two arguments and omitted
null
when called:public String getFoo(Int32 a) { return getBar(a, "b", null); } public String getBar(Int32 a, String b) { //do something else, without the int }
You probably don't want to do this though, since you stated that you want to avoid duplicating code.
-
Use
default
insteadnull
:return getBar(a, "b", default(int));
By the way, this is the same as passing a value
0
.
source to share