题
我有一个类,包含两种方法:
public String getFoo(Int32 a)
{
return getBar(a, "b", null);
}
public String getBar(Int32 a, String b, Int32 c)
{
//do something
return "";
}
然而,当我汇编我的课我让两个错误:
- 最好的超载方法的匹配getBar(int,string,int)拥有某一无效的论点
- 参数'3':不能把'
<null>
'到'int'
我想我明白为什么我得到这个错误:编译器不知道 当时的汇编什么是真正的种类型的对象。有人可以确认,如果我是正确的关于差错的原因或者指出,真正的原因是什么?
更重要的是,我可以设计,我的代码这样?如果是这样,什么我需要做到修复的错误?我的原因我的设计类这种方式是因为我不想重复代码在getBar,在:getFoo.两个方法都基本上相同的事情除了一个需要一个第三个参数。
谢谢。
解决方案
在.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)
{
}
其他提示
Int32
是一个值类型,这意味着null
不是int?
类型参数的有效参数。
如果您确实需要可为空的整数,请使用<=>类型。
您看到的两个错误实际上是同一个错误。
Sunny是正确的。
Int32是值类型,不能保存值“null”。如果需要传递'null'作为参数值,请使用Nullable而不是Int32作为参数类型。
Int32是int的别名,它是一个值/非可空类型。对于它的可空版本,请使用System.Nullable或简单地使用'int?'。
另外不要忘记转换回不可为空的int:
int? nullable = ...;
int non_nullable = nullable??0;
其中数字表示如果它确实为空则应该采用什么值。
Int32不能为空。改为使其成为可以为空的类型:
public String getBar(Int32 a, String b, Int32? c)
{
if (c.HasValue)
{
...do something with c.Value...
}
return "";
}
好吧,所以 五个七个人建议 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
.