Передача нулевых аргументов в методы C #

Есть ли способ передать нулевые аргументы методам C # (что-то вроде нулевых аргументов в С ++)?

Например:

Можно ли перевести следующую функцию c ++ в метод C #:

private void Example(int* arg1, int* arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}

person Niko Gamulin    schedule 07.11.2008    source источник


Ответы (7)


да. В .NET существует два типа типов: ссылочные типы и типы значений.

Типы ссылок (обычно классы) всегда упоминаются ссылками, поэтому они поддерживают null без дополнительной работы. Это означает, что если тип переменной является ссылочным типом, переменная автоматически становится ссылкой.

Типы значений (например, int) по умолчанию не имеют понятия null. Однако для них есть оболочка Nullable. Это позволяет вам инкапсулировать тип значения, не допускающий значения NULL, и включить в него нулевую информацию.

Однако использование немного отличается.

// 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.
}
person Sander    schedule 07.11.2008
comment
Подскажите, пожалуйста, разницу ч / б private void Example(int? arg1) и private void Example(int? arg1 = 0) - person Unbreakable; 30.10.2017
comment
@Unbreakable Если вы еще не догадались, в первом примере всегда требуется передавать arg1. Второй пример позволяет вам вызывать метод без передачи arg1, что означает, что по умолчанию он будет равен 0. - person user1779775; 23.08.2018
comment
Хороший ответ! Вы сказали, что это означает, что если тип переменной является ссылочным типом, переменная автоматически становится ссылкой. но я думаю, что здесь также следует отметить, что это не тот случай, когда значение этого ссылочного типа равно null. Есть мысли по этому поводу? - person Zimano; 29.02.2020

Я думаю, что ближайшим эквивалентом int* в C # будет ref int?. Потому что ref int? позволяет вызываемому методу передать значение обратно вызывающему методу.

int*

  • Может быть нулевым.
  • Может быть ненулевым и указывать на целочисленное значение.
  • Если не null, значение можно изменить, и изменение распространяется на вызывающего.
  • Значение null не передается обратно вызывающей стороне.

ref int?

  • Может быть нулевым.
  • Может иметь целочисленное значение.
  • Значение всегда можно изменить, и изменение распространяется на вызывающего абонента.
  • Значение можно установить равным нулю, и это изменение также будет распространено на вызывающего.
person mackenir    schedule 07.11.2008

Для этого вы можете использовать NullableValueTypes (например, int?). Код будет таким:

private void Example(int? arg1, int? arg2)
{
    if(!arg1.HasValue)
    {
        //do something
    }
    if(!arg2.HasValue)
    {
        //do something else
    }
}
person MADMap    schedule 07.11.2008

Начиная с C # 2.0, вы можете использовать универсальный тип Nullable, допускающий значение NULL, а в C # существует сокращенная запись, за которой следует тип?

e.g.

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
person user35412    schedule 07.11.2008

Из C # 2.0:

private void Example(int? arg1, int? arg2)
{
    if(arg1 == null)
    {
        //do something
    }
    if(arg2 == null)
    {
        //do something else
    }
}
person Marcin K    schedule 07.11.2008

На вопрос OP уже дан хороший ответ, но название достаточно широкое, и я думаю, что он выиграет от следующего учебника:

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() + "#");
        }
    }
}

вывод:

#1/1/0001 12:00:00 AM#
##
Done.  Return to quit
person ruffin    schedule 05.12.2012

Вы можете использовать 2 способа: int? или Nullable, оба имеют одинаковое поведение. Вы можете сделать микс без проблем, но это лучший выбор, чтобы сделать код максимально чистым.

Вариант 1 (С?):

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

Вариант 2 (с допускающим значение NULL):

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

В C # 4.0 появился новый способ сделать то же самое с большей гибкостью, в этом случае фреймворк предлагает необязательные параметры со значениями по умолчанию, таким образом вы можете установить значение по умолчанию, если метод вызывается без всех параметров.

Вариант 3 (со значениями по умолчанию)

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