刚从Java转到c#,对c#和dotnet平台了解还不深,这里只是发表一下个人从java角度对c#的理解。
今天刚刚看到c#中的函数委托机制,觉得c#中这个机制非常好,给编程以很大的方便。Java中只有对象的引用,而c#中增加了对值类型(c#中的值类型包括 primitives,枚举和结构体)的引用和函数的引用。
个人觉得值类型的引用用处不大,不仅对提高c#程序的质量没有什么意义,而且会使没有经验的程序员滥用它。比如,一个函数的有一个ref参数或者out参数,那么函数对这个引用参数的值的修改都会影响到外部程序的变量的值,无形中增加了函数和外部程序的耦合性。 class Program { static void double(ref int i) { i *= 2; }
static void main(string[] args) { int i = 3; double(i); } }
而函数的引用(函数委托就是一种用引用表示函数的机制)则相当有用。试想想,函数的引用本质上是把一个代码块用一个引用变量来表示,你可以根据不同的情况,选择不同的代码块,然后执行它。这种特性在java和c中是不曾提供的(Java中可以用模式实现),它可以大大减少我们代码量,运用这种特性也可以使我们面对变化的需求时修改的代码量更少。 代码块1 #region Using directives
using System; using System.Collections.Generic; using System.Text;
#endregion
namespace Ch06Ex05 { class Program { delegate double ProcessDelegate(double param1, double param2);
static double Multiply(double param1, double param2) { return param1 * param2; }
static double Divide(double param1, double param2) { return param1 / param2; }
static void Main(string[] args) { ProcessDelegate process; Console.WriteLine("Enter 2 numbers separated with a comma:"); string input = Console.ReadLine(); int commaPos = input.IndexOf(','); double param1 = Convert.ToDouble(input.Substring(0, commaPos)); double param2 = Convert.ToDouble(input.Substring(commaPos + 1, input.Length - commaPos - 1)); Console.WriteLine("Enter M to multiply or D to divide:"); input = Console.ReadLine(); if (input == "M") process = new ProcessDelegate(Multiply); else process = new ProcessDelegate(Divide); Console.WriteLine("Result: {0}", process(param1, param2)); Console.ReadKey(); } } } 上面这个程序先要求用户输入两个数,然后根据用户的要求选择是进行乘法运算还是除法运算,最后算出结果。我们再来看看同样的功能用java怎么实现。
Computer.java package test;
public interface Computer { Double compute(Double x, Double y); } Multiply.java package test;
public class Multiply implements Computer {
public Double compute(Double x, Double y) { Double re = x*y; return re; } } Divide.java package test;
public class Divide implements Computer {
public Double compute(Double x, Double y) { Double re = x/y; return re; } } Compute.java package test;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
public class Compute { public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Enter 2 numbers separated with a comma:"); String str = stdin.readLine(); String[] num = str.split(","); Double param1 = Double.valueOf(num[0]); Double param2 = Double.valueOf(num[1]); System.out.println("Enter M to multiply or D to divide:"); String input = stdin.readLine(); Computer cm; if (input.equals("M")) { cm = new Multiply(); } else { cm = new Divide(); } System.out.println("Result: " + cm.compute(param1, param2)); } } 从上面的c#代码和java代码的比较中,我们可以看出,代码量的差别还是很大的。C#的函数委托功能还是能为我们提供不少方便的。不过我个人觉的java更面向对象些,不知道是不是个人喜好在作怪。但是实践最能说明问题,一定要务实,一定要务实。
代码块2 #region using directives
using System; using System.Collections.Generic; using System.Text;
#endregion
namespace ConsoleApplication1 { delegate void SampleDelegate(string message);
class MainClass { static void Main() { // Instantiate delegate with named method: SampleDelegate d1 = delegate(string message) { Console.WriteLine("d1 " + message); }; // Instantiate delegate with anonymous method: SampleDelegate d2 = delegate(string message) { Console.WriteLine("d2" + message); };
// Invoke delegate d1: d1("Hello"); // Invoke delegate d2: d2(" World");
Console.ReadKey(); } } }