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.

+1


source to share


7 replies


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)
{
}

      

+8


source


Try making the third argument getBar

nullable int.

So, the signature will look like this:



public String getBar(Int32 a, String b, Int32? c)

      

You can read more about nullable types in .NET here and.

+2


source


Int32

is a value type, which means it is null

not a valid argument for type parameters Int32

.

If you really want null ints, use type int?

.

The two errors you see are actually the same error.

+1


source


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.

+1


source


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.

+1


source


Int32 cannot be null. Make it type null instead:

public String getBar(Int32 a, String b, Int32? c)
{
    if (c.HasValue)
    {
        ...do something with c.Value...
    }
    return "";
}

      

0


source


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

    .

0


source







All Articles