学习笔记《C#入门经典(第6版)》C#语言:第6章

一:参数数组

C#允许为函数指定一个(只能指定一个)特殊参数,这个参数必须是函数定义中的最后一个参数,称为参数数组。参数数组允许使用个数不定的参数调用函数,可以使用params关键字定义它们。例如:


static int sumVal(params int[] vals)
        {
            int sum = 0;
            foreach(int val in vals){
                sum += val;
            }
            return sum;
        }
        static void Main(string[] args)
        {
            int sum = sumVal(1, 5, 2, 8, 9);
            Console.WriteLine("Summed Value = {0}", sum);
            Console.ReadKey();
        }

二:传值调用

C#C/C++一样,默认的也是传值调用函数

 

三:使用引用来传递函数参数

C++当中有引用的机制,C#当中也有。在C#当中使用ref关键字来指定参数,使其成为引用。关于引用的好处,在学习C++时就已经了解过。注意在C#当中,在函数的定义和函数的调用时都得使用ref关键字来指定。如下:

static void ShowDouble(ref int val)
        {
            val *= 2;
            Console.WriteLine("val doubled = {0}", val);
        }
        static void Main(string[] args)
        {
            int val = 5;
            ShowDouble(ref val);
            Console.ReadKey();

        }

注意用作ref参数的变量有两个限制:1,必须在函数调用中使用“非常量”。2,变量必须是已经初始化过的。


四:输出参数

使用out关键字,所指定的参数是一个输出参数。Out关键字的使用方式与ref相同。该参数的值将返回给函数调用中使用的变量。

Outref的区别如下:

把未赋值的变量作ref参数是非法的,但可以将未赋值的变量用作out参数

在函数使用out参数时,必须把它看成是尚未赋值的。

 

注意:可以把已赋值的变量用作out参数,但存储在该变量中的值会在函数执行时丢失。

例如:

static int MaxValue(int[] intArray, out int maxIndex)
        {
            int maxVal = intArray[0];
            maxIndex = 0;
            for (int i = 0; i < intArray.Length; i++)
            {
                if (intArray[i] > maxVal)
                {
                    maxVal = intArray[i];
                    maxIndex = i;
                }
            }
            return maxVal;
        }

五:变量作用域

关于变量作用域,看一个出错的例子。代码如下:

int i;
            string text;
            for (i = 0; i < 10; i++)
            {
                text = "Line " + Convert.ToString(i);
                Console.WriteLine("{0}", text);
            }
            Console.WriteLine("Last text output in loop: {0}", text);

出错原因:必须在使用变量之前对其进行初始化,但text只在for循环中初始化。由于没有在循环外进行初始化,付给text的值在循环块退出时就丢失了。可以将程序改正如下即可。

int i;
            string text = "";
            for (i = 0; i < 10; i++)
            {
                text = "Line " + Convert.ToString(i);
                Console.WriteLine("{0}", text);
            }
            Console.WriteLine("Last text output in loop: {0}", text);

六:结构函数

结构函数与C++当中带函数的结构体是类似的。也即是在结构类型当中不仅可以包含数据,还可以包含函数。如下:

struct CustomerName
        {
            public string firstName, lastName;
            public string name()
            {
                return firstName + " " + lastName;
            }
        }

七:函数的重载

函数的重载与C++中的函数重载也类似。

八:委托(delegate

委托是一种存储函数引用的类型。

委托的声明类似于函数,但不带函数体,而且要使用关键字delegate。委托的声明指定了一个返回类型和一个参数列表。

定义了委托之后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。

有了引用函数的变量之后,就可以执行不能用其他方式完成的操作。例如,可以把委托变量作为参数传递给一个函数,这样,该函数就可以使用委托调用它引用的任何函数,而且在运行之前不必知道调用的是哪个函数。如下面的例子:

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();
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章