C#编译器抛出无效参数错误。为什么?

时间:2008-11-06 21:22:57

标签: .net c#-2.0

我有一个包含两个方法的类:

public String getFoo(Int32 a)
{
  return getBar(a, "b", null);
}

public String getBar(Int32 a, String b, Int32 c)
{
  //do something
  return "";
}

然而,当我编译我的课时,我得到两个错误:

  1. getBar(int,string,int)的最佳重载方法匹配具有一些无效参数
  2. 参数'3':无法从'<null>'转换为'int'
  3. 我想我明白为什么我会收到这个错误:编译器不知道 在编译时,对象的真实类型是什么。 有人可以确认我是否对错误的原因是正确的还是指出了真正的原因?

    更重要的是,我可以这样设计我的代码吗?如果是这样,我需要做些什么来修复错误?我这样设计我的类的原因是因为我不想在getFoo中的getBar中复制代码。这两种方法基本上是相同的,除了一个采用第三个参数。

    感谢。

7 个答案:

答案 0 :(得分:8)

在.NET中,引用类型和值类型之间存在明显的概念。

引用类型是在堆上分配的对象(它将是System.Object的子类)。堆栈上的所有内容都是指向此对象的指针。因此,存储空指针是完全有效的。

值类型是在堆栈上分配的对象,它将是System.ValueType的子类。由于值类型存在于堆栈中,因此将值传递给函数时,会传递对象的全部内容。

值类型不能为空。

大多数C#基元类型都是值类型。 String是一种特殊类型的基元,实际上是一种引用类型。

在.NET 2.0中,MS添加了将泛型类型包含在结构内部的功能,以便它可以模拟可为空的类型。真正发生的是Nullable&lt; T&gt;内部的逻辑。 struct正在为你模拟一个null。

他们使用语法快捷方式通过向类型添加问号来表达它,例如:

int? nullableInt = null;
float? nullableFloat = null;

等...

如果你不喜欢int?语法,您始终可以使用Nullable&lt; SomeType&gt;

public String getBar(Int32 a, String b, Nullable<Int32> c)

作为旁注,我更喜欢在做你正在做的事情时添加一个重载,只是为了使语法更好。

public String getBar(Int32 a, String b)
{
     this.getBar(a,b,null);
}

public String getBar(Int32 a, String b, Nullable<Int32> c)
{
}

答案 1 :(得分:2)

尝试将第三个参数设为getBar一个可空的int。

所以,签名看起来像这样:

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

您可以在.NET herehere中找到有关可空类型的更多信息。

答案 2 :(得分:1)

Int32是一种值类型,这意味着null不是Int32类型参数的有效参数。

如果您确实需要可为空的整数,请使用int?类型。

您看到的两个错误实际上是同一个错误。

答案 3 :(得分:1)

Int32是int的别名,它是一个值/非可空类型。对于它的可空版本,请使用System.Nullable或简单地使用'int?'。

另外不要忘记转换回不可为空的int:

int? nullable = ...;
int non_nullable = nullable??0; 

其中数字表示如果它确实为空则应该采用什么值。

答案 4 :(得分:1)

Sunny是正确的。
Int32是值类型,不能保存值“null”。如果需要传递'null'作为参数值,请使用Nullable而不是Int32作为参数类型。

您可以在MSDN上的Nullable Types (C# Programming Guide)找到更多信息。

答案 5 :(得分:0)

Int32不能为空。改为使其成为可以为空的类型:

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

答案 6 :(得分:0)

好的,所以七个人建议int?作为解决方案。我建议另外两个可能更合适的解决方案,具体取决于具体情况;

  • 创建只有两个参数的方法的重载,并在调用时省略null

    public String getFoo(Int32 a)
    {
      return getBar(a, "b", null);
    }
    
    public String getBar(Int32 a, String b)
    {
      //do something else, without the int
    }
    

    虽然您可能不想这样做,因为您声明要避免代码重复。

  • 使用default代替null

    return getBar(a, "b", default(int));
    

    顺便提一下,这与传递值0

  • 相同