【问题标题】:Passing null arguments to C# methods将空参数传递给 C# 方法
【发布时间】:2008-11-07 09:13:10
【问题描述】:

有没有办法将空参数传递给 C# 方法(类似于 c++ 中的空参数)?

例如:

是否可以将以下 c++ 函数转换为 C# 方法:

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

【问题讨论】:

    标签: c# methods null


    【解决方案1】:

    是的。 .NET 中有两种类型:引用类型和值类型。

    引用类型(通常是类)总是由引用引用,因此它们支持 null 而无需任何额外工作。这意味着如果变量的类型是引用类型,则该变量自动成为引用。

    默认情况下,值类型(例如 int)没有 null 的概念。但是,它们有一个称为 Nullable 的包装器。这使您可以封装不可为空的值类型并包含空信息。

    不过,用法略有不同。

    // 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.
    }
    

    【讨论】:

    • 你能告诉我 b/w private void Example(int? arg1)private void Example(int? arg1 = 0) 的区别
    • @Unbreakable 如果你现在还没有想通,第一个例子总是需要传入arg1。第二个例子允许你在不传入arg1的情况下调用方法,这意味着它将默认为 0。
    • 好答案!您说“这意味着如果变量的类型是引用类型,则该变量自动成为引用。”但我认为这里还应该注意的是,当该引用类型的值为null 时,情况并非如此。对此有什么想法吗?
    【解决方案2】:

    您可以为此使用 NullableValueTypes(如 int?)。代码是这样的:

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

    【讨论】:

      【解决方案3】:

      您可以使用 2 种方式:int?或 Nullable,两者具有相同的行为。您可以毫无问题地进行混合,但更好的选择是使代码最干净。

      选项 1(带 ?):

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

      选项2(可以为空):

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

      从 C#4.0 开始,提供了一种新的方式来做同样的事情,并且更灵活,在这种情况下,框架提供了optional parameters with default values,如果在没有所有参数的情况下调用该方法,您可以设置一个默认值。

      选项 3(使用默认值)

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

      【讨论】:

        【解决方案4】:

        来自 C# 2.0:

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

        【讨论】:

          【解决方案5】:

          我认为与<strong>int*</strong> 等价的最接近的C# 将是<strong>ref int?</strong>。因为<strong>ref int?</strong> 允许被调用的方法将值传回给调用的方法。

          <strong>int*</strong>

          • 可以为空。
          • 可以是非空值并指向一个整数值。
          • 如果不为 null,则可以更改值,并将更改传播给调用者。
          • 设置为 null 不会传回给调用者

          <strong>ref int?</strong>

          • 可以为空。
          • 可以有一个整数值。
          • 值可以随时更改,并且更改会传播给调用者。
          • 值可以设置为null,这个变化也会传播到调用者

          【讨论】:

            【解决方案6】:

            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
            

            【讨论】:

              【解决方案7】:

              从 C# 2.0 开始,您可以使用可为空的泛型类型 Nullable,而在 C# 中,类型后面有一个简写符号 ?

              例如

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

              【讨论】:

                猜你喜欢
                • 2013-02-08
                • 1970-01-01
                • 1970-01-01
                • 2011-10-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-07-23
                相关资源
                最近更新 更多