⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 123456.txt

📁 c#编程入门,我在其它网站收集的."功能描述要求的字数太多能不能少一点"
💻 TXT
📖 第 1 页 / 共 5 页
字号:

4.1.1.3  字符型  
    字符型为一个单Unicode 字符。一个Unicode字符16位长,它可以用来表示世界上多种语言。可以按以下方法给一个字  
符变量赋值:  
char chSomeChar = ’A’;  
     除此之外,可以通过十六进制转义符(前缀x)或Unicode表示法给变量赋值(前缀u):  
char chSomeChar = ’x0065’;  
char chSomeChar = ’u0065’;  
    不存在把char转换成其它数据类型的隐式转换。这就意味着,在C#中把一个字符变量当作另外的整数数据类型看待是  
行不通的——这是C程序员必须改变习惯的另一个方面。但是,可以运用显式转换:  
char chSomeChar = (char)65;  
int nSomeInt = (int)’A’;  
      在C中仍然存在着转义符(字符含义)。要换换脑筋,请看表4.1。  

Table 4.1 转义符( Escape Sequences)  

转义符                  字符名  
’                            单引号  
"                           双引号  
\                           反斜杠  



 前一章讨论了数据类型和它们的用法。现在我们转移到C#中至关重要的结构——类。没有了类,就连简单的C#程序  
都不能编译。这一章假定你知道了一个类的基本组成部分:方法、属性、构造函数和析构函数。 C#在其中增加了索引和事  
件。  
       在这一章中,你学到下列有关类的话题。  
      。 使用构造函数和析构函数  
      。给类写方法  
      。给一个类增加属性存取标志  
      。实现索引  
      。创建事件并通过代表元为事件关联客户  
      。应用类、成员和存取修饰符。  

5.1  构造函数和析构函数  
          在你可以访问一个类的方法、属性或任何其它东西之前, 第一条执行的语句是包含有相应类的构造函数。甚至  
你自己不写一个构造函数,也会有一个缺省的构造函数提供给你。  

class TestClass  
{  
public TestClass(): base() {} // 由编译器提供  
}  

       一个构造函数总是和它的类名相同,但是,它没有声明返回类型。总之,构造函数总是public的,你可以用它们来  
初始化变量。  

public TestClass()  
{  
// 在这给变量  
// 初始化代码等等。  
}  

       如果类仅包含静态成员(能以类型调用,而不是以实例调用的成员),你可以创建一个private的构造函数。  
private TestClass() {}  
       尽管存取修饰符在这一章的后面将要大篇幅地讨论,但是private意味着从类的外面不可能访问该构造函数。所  
以,它不能被调用,且没有对象可以自该类定义被实例化。  
       并不仅限于无参数构造函数——你可以传递初始参数来初始化成员。  
       public TestClass(string strName, int nAge) { ... }  

       作为一个C/C++程序员,你可能习惯于给初始化写一个附加的方法,因为在构造函数中没有返回值。当然,尽管在  
C#中也没有返回值,但你可以引发一个自制的异常,以从构造函数获得返回值。更多有关异常处理的知识在第七章 "异常  
处理"中有讨论。  
       但是,当你保留引用给宝贵的资源,应该想到写一个方法来解决:一个可以被显式地调用来释放这些资源。问题是  
当你可以在析构函数(以类名的前面加"~"的方式命名)中做同样的事情时,为何还要写一个附加的方法.  
public ~TestClass()  
{  
// 清除  
}  

    你应该写一个附加方法的原因是垃圾收集器,它在变量超出范围后并不会立即被调用,而仅当间歇期间或内存条件满  
足时才被触发。当你锁住资源的时间长于你所计划的时间时,它就会发生。因此,提供一个显式的释放方式是一个好主  
意,它同样能从析构函数中调用。  

public void Release()  
{  
// 释放所有宝贵的资源  
}  

public ~TestClass()  
{  
Release();  
}  

    调用析构函数中的释放方法并不是必要的——总之,垃圾收集会留意释放对象。但没有忘记清除是一种良好的习惯。  

5.2  方法  
     既然对象能正确地初始化和结束,所剩下来的就是往类中增加功能。在大多数情况下,功能的主要部分在方法中能得  
到实现。你早已见过静态方法的使用,但是,这些是类型(类)的部分,不是实例(对象)。  
    为了让你迅速入门,我把这些方法的烦琐问题安排为三节:  
。方法参数  
。改写方法  
。方法屏蔽  
5.2.1  方法参数  
  因方法要处理更改数值,你多多少少要传递值给方法,并从方法获得返回值。以下三个部分涉及到由传递值和为调用者  
获取返回结果所引起的问题。  

。输入参数  
。引用参数  
。输出参数  

5.2.1.1  输入参数  
  你早已在例子中见过的一个参数就是输入参数。你用一个输入参数通过值传递一个变量给一个方法——方法的变量被调  
用者传递进来的值的一个拷贝初始化。清单5.1 示范输入参数的使用。  

清单  5.1 通过值传递参数  

1: using System;  
2:   
3: public class SquareSample  
4: {  
5:  public int CalcSquare(int nSideLength)  
6:  {  
7:   return nSideLength*nSideLength;  
8:  }  
9: }  
10:   
11: class SquareApp  
12: {  
13:  public static void Main()  
14:  {  
15:   SquareSample sq = new SquareSample();  
16:   Console.WriteLine(sq.CalcSquare(25).ToString());  
17:  }  
18: }  

   因为我传递值而不是引用给一个变量,所以当调用方法时(见第16行),可以使用一个常量表达式(25)。整型结果被传回  
给调用者作为返回值,它没有存到中间变量就被立即显示到屏幕上 。  
    输入参数按C/C++程序员早已习惯的工作方式工作。如果你来自VB,请注意没有能被编译器处理的隐式ByVal或ByRef—  
—如果没有设定,参数总是用值传递。  
     这点似乎与我前面所陈述的有冲突:对于一些变量类型,用值传递实际上意味着用引用传递。迷惑吗? 一点背景知识  
也不需要:COM中的东西就是接口,每一个类可以拥有一个或多个接口。一个接口只不过是一组函数指针,它不包含数据。  
重复该数组会浪费很多内存资源;所以,仅开始地址被拷贝给方法,它作为调用者,仍然指向接口的相同指针。那就是为  
什么对象用值传递一个引用。  

5.2.1.2  引用参数  
    尽管可以利用输入参数和返回值建立很多方法,但你一想到要传递值并原地修改它(也就是在相同的内存位置),就没  
有那么好运了。这里用引用参数就很方便。  
void myMethod(ref int nInOut)  
   因为你传递了一个变量给该方法(不仅仅是它的值),变量必须被初始化。否则,编译器会报警。清单 5.2 显示如何用  
一个引用参数建立一个方法。  

清单 5.2  通过引用传递参数  

1: // class SquareSample  
2: using System;  
3:   
4: public class SquareSample  
5: {  
6:  public void CalcSquare(ref int nOne4All)  
7:  {  
8:   nOne4All *= nOne4All;  
9:  }  
10: }  
11:   
12: class SquareApp  
13: {  
14:  public static void Main()  
15:  {  
16:   SquareSample sq = new SquareSample();  
17:   
18:   int nSquaredRef = 20; // 一定要初始化  
19:   sq.CalcSquare(ref nSquaredRef);  
20:   Console.WriteLine(nSquaredRef.ToString());  
21:  }  
22: }  

   正如所看到的,所有你要做的就是给定义和调用都加上ref限定符。因为变量通过引用传递,你可以用它来计算出结果  
并传回该结果。但是,在现实的应用程序中,我强烈建议要用两个变量,一个输入参数和一个引用参数。  

5.2.1.3  输出参数  
   传递参数的第三种选择就是把它设作一个输出参数。正如该名字所暗示,一个输出参数仅用于从方法传递回一个结果。  
它和引用参数的另一个区别在于:调用者不必先初始化变量才调用方法。这显示在清单5.3中。  

清单  5.3  定义一个输出参数  

1: using System;  
2:   
3: public class SquareSample  
4: {  
5:  public void CalcSquare(int nSideLength, out int nSquared)  
6:  {  
7:   nSquared = nSideLength * nSideLength;  
8:  }  
9: }  
10:   
11: class SquareApp  
12: {  
13:  public static void Main()  
14:  {  
15:   SquareSample sq = new SquareSample();  
16:     
17:   int nSquared; // 不必初始化  
18:   sq.CalcSquare(15, out nSquared);  
19:   Console.WriteLine(nSquared.ToString());  
20:  }  
21: }  


5.2.2  改写方法  
    面向对象设计的重要原则就是多态性。不要理会高深的理论,多态性意味着:当基类程序员已设计好用于改写的方法  
时,在派生类中,你就可以重定义(改写)基类的方法。基类程序员可以用 virtual 关键字设计方法:  
virtual void CanBOverridden()  
    当从基类派生时,所有你要做的就是在新方法中加入override关键字:  
override void CanBOverridden()  
    当改写一个基类的方法时,你必须明白,不能改变方法的访问属性——在这章的后面,你会学到更多关于访问修饰符  
的知识。  
    除了改写基类方法的事实外,还有另一个甚至更重要的改写特性。当把派生类强制转换成基类类型并接着调用虚拟方  
法时,被调用的是派生类的方法而不是基类的方法。  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -