在使用C#之前,我们可能使用了不同的语言,体验着不同的编程环境和背景。这导致我们的方法(或者说函数)的长度有着不同的看法。
极端的面向过程编程人员会见过这样的规范:任何函数都不要超过20行;但是给单片机写程序的人可能有着完全不同的规范:函数调用不能超过5层,极可能把功能写在一个函数里。
这是由不同的需求造成的:前者要求尽可能的分割功能,体现出面向过程编程对功能分割的优势;后者是因为没有足够的空间实现长长的调用堆栈,必须尽可能的为节省内存而考虑。
那么在C#中,我们的方法该写多长呢?
事实上,我们应该使用 短小的、思路清晰的方法。
或许你会说,上的方法会尽量节省函数调用的成本,但是,或许在之前的某些地方这样没错,现在我们谈的是C#,情况并不是这样。
我们都知道,在C#中代码先被变成IL,然后在运行前被JIT编译成Native Code。JIT是按照方法进行编译的,也就是说它会在真正需要某一个方法之前编译它。这样,尽可能小的方法会减少我们程序的载入时间。
我们看下面的一段代码:
不管 Directory.Exists(filePath)返回的是true还是false,两个代码块中的代码都会被编译。
如果写成这样:
调用的两个方法中盛放之前的两个代码快。则只会在Directory.Exists(filePath)返回true或false时编译二者中的一个方法。这样,程序的载入时间必然会缩短。
这个例子只是一种简单的特殊的情况,真正的情况是:有人会在程序中写上一个几百行的方法,或是在某个很少会进入的逻辑分支里写了大量的逻辑。这都会加重程序载入的负担。
JIT编译器会正确的进行函数的内联等处理,不需要我们对它进行太多的干预。相反的是,我们手工干预得越多,越是难以让JIT编译器自己选择较优的方法。正确的方法是:写短小,清晰的方法。这样不会让我们的程序变慢,而会使我们的程序更容易理解,载入更快。
参考:《C#高级编程》《.NET大局观》《Effective C#》
极端的面向过程编程人员会见过这样的规范:任何函数都不要超过20行;但是给单片机写程序的人可能有着完全不同的规范:函数调用不能超过5层,极可能把功能写在一个函数里。
这是由不同的需求造成的:前者要求尽可能的分割功能,体现出面向过程编程对功能分割的优势;后者是因为没有足够的空间实现长长的调用堆栈,必须尽可能的为节省内存而考虑。
那么在C#中,我们的方法该写多长呢?
事实上,我们应该使用 短小的、思路清晰的方法。
或许你会说,上的方法会尽量节省函数调用的成本,但是,或许在之前的某些地方这样没错,现在我们谈的是C#,情况并不是这样。
我们都知道,在C#中代码先被变成IL,然后在运行前被JIT编译成Native Code。JIT是按照方法进行编译的,也就是说它会在真正需要某一个方法之前编译它。这样,尽可能小的方法会减少我们程序的载入时间。
我们看下面的一段代码:
public
static
void
CheckDirectoryExist(
string
filePath)
{
StringBuilder msg = new StringBuilder();
if (Directory.Exists(filePath))
{
msg.Append("The directory ");
msg.Append(filePath);
msg.Append(" has been exists");
}
else
{
Directory.CreateDirectory(filePath);
msg.Append("The directory ");
msg.Append(filePath);
msg.Append(" has been created.");
}
return msg.ToString();
}
{
StringBuilder msg = new StringBuilder();
if (Directory.Exists(filePath))
{
msg.Append("The directory ");
msg.Append(filePath);
msg.Append(" has been exists");
}
else
{
Directory.CreateDirectory(filePath);
msg.Append("The directory ");
msg.Append(filePath);
msg.Append(" has been created.");
}
return msg.ToString();
}
不管 Directory.Exists(filePath)返回的是true还是false,两个代码块中的代码都会被编译。
如果写成这样:
public
static
void
CheckDirectoryExist(
string
filePath)
{
if (Directory.Exists(filePath))
{
return DirectoryExists();
}
else
{
return DirectoryNotExists();
}
}
{
if (Directory.Exists(filePath))
{
return DirectoryExists();
}
else
{
return DirectoryNotExists();
}
}
调用的两个方法中盛放之前的两个代码快。则只会在Directory.Exists(filePath)返回true或false时编译二者中的一个方法。这样,程序的载入时间必然会缩短。
这个例子只是一种简单的特殊的情况,真正的情况是:有人会在程序中写上一个几百行的方法,或是在某个很少会进入的逻辑分支里写了大量的逻辑。这都会加重程序载入的负担。
JIT编译器会正确的进行函数的内联等处理,不需要我们对它进行太多的干预。相反的是,我们手工干预得越多,越是难以让JIT编译器自己选择较优的方法。正确的方法是:写短小,清晰的方法。这样不会让我们的程序变慢,而会使我们的程序更容易理解,载入更快。
参考:《C#高级编程》《.NET大局观》《Effective C#》