在一个项目里引用到另一个dll中的带有默认参数的方法时
static void Main(string[] args)
{
Test t = new Test();
t.Work();
}
在dll的最初实现为:
public class Test
{
public void Work(int a = 5, string name = "fudan")
{
Console.WriteLine("a:" + a + "\nname:" + name);
}
}
此时将会输出:
a:5
name:fudan
但是如果dll发生变化,并进行重新编译,而此时没有对Main方法进行重新编译,将会出错。如,dll改为:
public class Test
{
public void Work(int a = 10, string name = "tsing")
{
Console.WriteLine("a:" + a + "\nname:" + name);
}
}
如果main方法没有进行重新编译,则仍会输出:
a:5
name:fudan
这说明默认的行为出错了。真正的默认行为是:
a:5
name:fudan
原因:
C#编译器在编译时,如果发现没有给方法Work提供实参,则会对参数a与name采用默认参数,此时将在main方法上生成两个临时变量用将保存默认的值5与“fudan”,当方法运行时,将把这两个临时变量作为参数传送到方法Work上。因此,当重新生成新的dll时,并没有对main方法进行重新编译,所以,main方法传送的参数值并没有发生变化。为了使得默认的行为正确,只得重新编译。但是这样做并不合理,因此,最好的采用默认参数的方法是:对引用类型采用null,对值类型采用0.
如:
public class Test
{
public void Work(int a = 0, string name = null)
{
if(a
==0)a=10;
if(name==null) name="tsing";
Console.WriteLine("a:" + a + "\nname:" + name);
}
}
这样,进行修改时,可以不用重新编译Main方法,就可以实现默认行为的变化。对于小的项目而言,问题不大。但是对于类库的提供者而言,好像这个问题挺大的。