40

Is there a way to pass null arguments to C# methods (something like null arguments in c++)?

For example:

Is it possible to translate the following c++ function to C# method:

private void Example(int* arg1, int* arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
Niko Gamulin
  • 66,025
  • 95
  • 221
  • 286

7 Answers7

92

Yes. There are two kinds of types in .NET: reference types and value types.

References types (generally classes) are always referred to by references, so they support null without any extra work. This means that if a variable's type is a reference type, the variable is automatically a reference.

Value types (e.g. int) by default do not have a concept of null. However, there is a wrapper for them called Nullable. This enables you to encapsulate the non-nullable value type and include null information.

The usage is slightly different, though.

// Both of these types mean the same thing, the ? is just C# shorthand.
private void Example(int? arg1, Nullable<int> arg2)
{
    if (arg1.HasValue)
        DoSomething();

    arg1 = null; // Valid.
    arg1 = 123;  // Also valid.

    DoSomethingWithInt(arg1); // NOT valid!
    DoSomethingWithInt(arg1.Value); // Valid.
}
Sander
  • 25,685
  • 3
  • 53
  • 85
  • 1
    Can you kindly tell me the difference b/w `private void Example(int? arg1)` and `private void Example(int? arg1 = 0)` – Unbreakable Oct 30 '17 at 20:05
  • @Unbreakable If you haven't figured it out by now, the first example always requires arg1 to be passed in. The second example allows you to call the method without passing in arg1, meaning that it will default to 0. – user1779775 Aug 23 '18 at 11:39
  • Good answer! You said "This means that if a variable's type is a reference type, the variable is automatically a reference." but I think it should also be noted here that this isn't the case when the value of that reference type is `null`. Any thoughts on that? – Zimano Feb 29 '20 at 13:54
9

I think the nearest C# equivalent to int* would be ref int?. Because ref int? allows the called method to pass a value back to the calling method.

int*

  • Can be null.
  • Can be non-null and point to an integer value.
  • If not null, value can be changed, and the change propagates to the caller.
  • Setting to null is not passed back to the caller.

ref int?

  • Can be null.
  • Can have an integer value.
  • Value can be always be changed, and the change propagates to the caller.
  • Value can be set to null, and this change will also propagate to the caller.
mackenir
  • 10,801
  • 16
  • 68
  • 100
8

You can use NullableValueTypes (like int?) for this. The code would be like this:

private void Example(int? arg1, int? arg2)
{
    if(!arg1.HasValue)
    {
        //do something
    }
    if(!arg2.HasValue)
    {
        //do something else
    }
}
MADMap
  • 3,132
  • 3
  • 25
  • 31
5

From C# 2.0:

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
Marcin K
  • 751
  • 1
  • 8
  • 13
3

The OP's question is answered well already, but the title is just broad enough that I think it benefits from the following primer:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace consolePlay
{
    class Program
    {
        static void Main(string[] args)
        {
            Program.test(new DateTime());
            Program.test(null);
            //Program.test(); // <<< Error.  
            // "No overload for method 'test' takes 0 arguments"  
            // So don't mistake nullable to be optional.

            Console.WriteLine("Done.  Return to quit");
            Console.Read();
        }

        static public void test(DateTime? dteIn)
        {
            Console.WriteLine("#" + dteIn.ToString() + "#");
        }
    }
}

output:

#1/1/0001 12:00:00 AM#
##
Done.  Return to quit
ruffin
  • 16,507
  • 9
  • 88
  • 138
3

Starting from C# 2.0, you can use the nullable generic type Nullable, and in C# there is a shorthand notation the type followed by ?

e.g.

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
user35412
  • 39
  • 1
3

You can use 2 ways: int? or Nullable, both have the same behavior. You could to make a mix without problems but is better choice one to make code cleanest.

Option 1 (With ?):

private void Example(int? arg1, int? arg2)
    {
        if (arg1.HasValue)
        {
            //do something
        }
        if (arg1.HasValue)
        {
            //do something else
        }
    }

Option 2 (With Nullable):

private void Example(Nullable<int> arg1, Nullable<int> arg2)
    {
        if (arg1.HasValue)
        {
            //do something
        }
        if (arg1.HasValue)
        {
            //do something else
        }
    }

From C#4.0 comes a new way to do the same with more flexibility, in this case the framework offers optional parameters with default values, of this way you can set a default value if the method is called without all parameters.

Option 3 (With default values)

private void Example(int arg1 = 0, int arg2 = 1)
    {
        //do something else
    }