c#进阶params可变个数的参数
2010-12-28 02:55 撞破南墙 阅读(3819) 评论(6) 编辑 收藏 举报
系列索引
1简单使用
// NOTE: it is possible to pass the 'values'
// array to other methods if you want to.
Int32 sum = 0;
if (values != null) {
for (Int32 x = 0; x < values.Length; x++)
sum += values[x];
}
return sum;
}
明显他可以这样使用
// Displays "15"
Console.WriteLine(Add(new Int32[] { 1, 2, 3, 4, 5 } ));
}
但是这样有点丑,也许这样会漂亮点。params的特性
// Displays "15"
Console.WriteLine(Add(1, 2, 3, 4, 5));
}
但是哦呼,他真的可以运行。这是params参数的特权,去除params之后就会报错,因为他就变成了3个参数的函数了。是为了消除二义性,将不能再定义不带params 的函数。
2可变个数的参数params 的原理
在想params是如何实现的时候,我猜测params是编译器的语法糖在IL中不存在。打开reflactor来尝试验证
DisplayTypes(1, 3, 4);
DisplayTypes(new Object[] { 1, 3, 4 });
Console.Read();
}
private static void DisplayTypes(params Object[] objects) {
if (objects != null) {
foreach (Object o in objects)
Console.WriteLine(o.GetType());
}
}
对应的Main方法
public static void Main()
{
object[] CS$0$0000;
DisplayTypes(new object[] { (int) 1, (int) 3, (int) 4 });
DisplayTypes(new object[] { (int) 1, (int) 3, (int) 4 });
Console.Read();
return;
}果然不出所料。
3性能分析
其实质其实构造一个 array 在编译时确定其长度来 承载可变个数的参数.但性能上并不划算:因为需要额外构造一个array。
1在堆上分配内存
2初始化其元素
3最后还得被回收。
所以出于性能更好的做法是重载。我们可以看String 中Concat的做法。
public static string Concat(object arg0);
public static string Concat(object arg0, object arg1);
public static string Concat(object arg0, object arg1, object arg2);
public static string Concat(params object[] args);
public static string Concat(string str0, string str1);
public static string Concat(string str0, string str1, string str2);
public static string Concat(string str0, string str1, string str2, string str3);
public static string Concat(params string[] values);
}
4参数和返回值编写的较好实践:
1参数和返回值尽量使用接口和基类
显而易见,可以适用被更多种(派生)类型。
2常量性(const-ness)的对象和参数
类的常量性其实是自欺欺人,如前所述(我之前的一篇文章)我们虽然不能改变类的地址,但可以改变地址的值。这样的话C++等实现的常量性类,是在自欺欺人吗?其实我们可以在设计类的时候就不让他改变就得了?(private set),他也有很多不好的地方如 使得执行的时候需要检查是否是常量(不可改变)而降低性能。
作者:撞破南墙
出处:http://www.cnblogs.com/facingwaller/
关于作者:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。