2008-11-06 77 views
1

我有一个包含两个方法像这样一类:C#编译器抛出无效参数错误。为什么?

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

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

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

  1. 为getBar(整型,字符串,整数的最佳重载的方法匹配)有一些无效参数
  2. 参数 '3':无法从 '<null>' 转换为 'INT'

我想我unders为什么我得到这个错误:编译器在编译时不知道 什么是对象的实际类型。 有人可以确认我对错误原因是否正确或指出真实原因?

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

谢谢。

+0

谢谢大家。这正是我需要知道的。我有一个关于Int32的错误假设,因为我认为它是一个从System.Object继承的对象。乔纳森的回答真的解决了这个问题。 堆栈溢出岩石! – Notorious2tall 2008-11-06 21:36:15

回答

8

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

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

值类型是在堆栈上分配的对象,它将是System.ValueType的子类。由于值类型位于堆栈上,所以当您将其值传递给函数时,会传递该对象的全部内容。

值类型不能为空。

大多数C#基元类型都是值类型。字符串是实际上是引用类型的特殊类型的基元。

在.NET 2.0中,MS添加了在结构中封装通用类型的能力,以便它可以模拟可空类型。真正发生的是,Nullable <T>结构中的逻辑正在为你模拟一个null。

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

等等

如果你不喜欢INT:

他们使用的语法快捷方式添加一个问号的类型,例如表达呢?语法,你可以随时使用可空<SOMETYPE>

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

这是一个很好的答案。我时不时地回到它。 – Notorious2tall 2009-01-17 23:16:51

1

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

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

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

2

尝试使getBar为空的int的第三个参数。

所以,签名是这样的:

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

你可以找到更多关于可空类型在.NET herehere

1

int32是int的别名,它是一个值/不可为空的类型。对于它的可空版本,可以使用System.Nullable或简单的'int?'。

也不要忘记转换回一个非空的INT:

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

,其中数字表示什么值应该承担,如果它确实是空。

1

阳光是正确的。
Int32是一个值类型,不能包含值'null'。如果您需要将'null'作为参数值传递,请使用Nullable而不是Int32作为参数类型。

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

+0

具体来说,Int32是一个值类型,而null从来不是一个值类型的有效值。Null只对引用类型有效,它是从System.Object继承的任何东西。 – cfeduke 2008-11-06 21:31:00

0

Int32不能为空。使它成为一个可空类型,而不是:

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

OK,所以七人提出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

+0

他的重载仍然需要一个可为空的类型,或者需要大量的代码重复。 – FlySwat 2008-11-06 21:36:08

相关问题