1.0认识C#
之前我们学过了java 而C#语言和java语言都是面向对象的编程语言,两种语言的基本语法有很多的相似的地方,所以在学习的过程中,要注意和java语言的区别,在对比学习中快速进阶.
1.1.Net 概述与C#应用
.net是Microsoft.NET的简称,是基于Windows平台的一种技术.它包含了能在.NET Framework平台运行的所有编程语言. .NET Framework 是微软(Microsoft)为开发应用程序创建的一个富有革命性的新平台.
而C#是一种全新的语言,在设计它的时候微软博采众长,讲C,C++,JAVA等多种开发语言的优点集于一身,它是为.NET开发而设计的编程语言,是微软为奠定其下一代互联网霸主地位而打造的.
1.2第一个C#程序的创建
1.2.1新建程序
对.net和C#有了一定的认识后,下面就让我们来了解下c#程序的庐山真面目吧.先启动 Visual Studio 2012.而第一次运行vs需要配置环境 需要花费一定的时间
最后再新建项目 在菜单栏中选择 文件 - 新建 - 项目 弹出新建项目对话框。最后改名创建 就出来了 最后在ctrl+f5就可以直接运行了。
1.2.3认识C#程序
我们要把注意力都集中在Program.cs 文件上.在解决方案资源管理器中双击Progam.cs 可以打开文件 代码如示列所示.
using System;
using System.Collections.Generic;
using System.Ling;
using System.Text;
namespace yx
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.ReadLine();
}
}
}
对于这段程序 ,你可能会觉得熟悉又陌生 因为他类似于java上的东西 到底又几分相似 就让我们一层层的抛开开把.
1.namespace关键字
namespace(命名空间)是C#中组织代码的方式,它的作用类似于java中的package(包),这样我们就可以把紧密相关的一些代码放在同一个命名空间中,大大提高管理和使用的效率。在示列这段代码中,vs 自动以项目的名称 "Helloword"作为这段程序命名空间的名称.
2.using关键字
在java中,如果导入其他包,应该使用impor关键字。而在C#中,使用using关键字来引用其他命名空间,它的作用和java中的import类似。在示列这段代码模板生成是,vs就已经自动添加了四条using语句
3.class关键字
与java一样,C#也是一种面向对象的语言,使用class关键字表示类。我们编写的代码都应该包含在一个类里面,类包含在一个命名空间中。在程序模板生成时,vs自动创建了一个类,名为Program ,如果你不喜欢,可以改掉它,注意:C#与java不同,不要求类名必须与源文件的名称一样。
4.Main()方法
C#中的Main()方法和java中的main方法作用是一样的,是程序的出入口,应用程序从这里开始运行.但要注意的是,c#中的main()方法的返回值可以是void或者int类型,main()方法可以没有命令型参数。因此,这样组合一下,C#中的main()方法有四种形式.
语法如下
static void Main(String[] args){}
static int Main(string[]args){}
static void Main(){}
static int Main(){}
1.3 C#中的数据类型
每一种开发语言都有它的数据类型,c#语言有哪些数据类型呢?跟java中的数据类型有什么区别和联系吗?c#提供的数据类型与java非常相似。在这里列举最常用的数据类型,如表下所示.
常用数据类型 | java | C# | 举例 |
---|---|---|---|
整形 | int | int | 年龄 |
浮点型 | float | float | 成绩 |
双精度型 | double | double | 圆周率 |
字符串型 | String | string | 姓名 |
布尔型 | boolean | bool | 是否是少数名族 |
在为浮点型变量赋值时,C#语言要求赋值数据必须以字母f或f结束.
1.4c#中的常量
什么是常量?
常量就是在程序运行过程中保持不变的值,列如,示列2中Daymax表示一周的天数,应该是不变的,就可以定义为常量。常量定义的语法如下.
const数据类型常量名称 = 值;
列如
public const int Daymax = 7; // 定义常量dayMax
常量命名规则规范如下.
常量名称必须具有一定的实际意义.
常量名称最好以大写字母来命名,中间可根据意义的连接性用下划线做连接,每个常量定义的右侧最好有简单的注释,说明其作用。
常量名称长度最好不要超过25个字符,否则可读性差.
何时使用常量?
常量在程序是经常使用的,那么在什么情况下要使用常量呢?
用于在程序中一旦设定就不允许被修改的值.列如,圆周率的值在整个程序范围内一般是不能被随意修改的.
1.5 Console
console是C#中的控制台类,利用它能很方便地进行控制台的输入/输出。常用的输出方法有两个:console.writelne()和console.readline()他们唯一的区别就是在输出后换行,后者输出后不换行,常用的输出方法有console.readline,改方法的返回string类型。
利用console.writeLine()方法输出有三种方式.
方式一
Console.writeLine()
方式二
Console.writeLine(要输出的值);
方式三
Console.writeline("格式字符串",变量列表);0
1.5.1从控制台读入
语法
Console.ReadLine();
这句话放回一个字符串,可以直接把他赋给一个字符串变量,
如果需要输入整型数据怎么办?只需要一个简单的转换就可以了
int age = int.Parse(Console.ReadLine());
1.6自定义方法
语法
[访问修饰符]返回值 方法名(参数列表)
{
//方法的主体
}
1.访问修饰符
一个是public 公用的 另一个是private 私有的
2.方法的返回值类型
我们编写的方法是实现特定功能的模块,客供他人调用在调用后可以返回一个值,这个返回值的数据类型就是方法的返回值类型,可以是int,float double bool string等 。如果方法不返回任何值 需要使用void关键字.
3.方法名
每个自定义的方法都要有一个名称,方法的名称应该有明确的含义,这样比尔在使用的时候就能清楚地知道这个方法能实现什么功能。列如,我们用了无数遍的writeline()方法,从名称上就知道输出一行信息的意思.
4.参数列表
调用方法时,可以向方法中传递参数,这些参数构成了参数列表,如果没有参数就不用参数表。参数列表中的每给参数都是通过“类型参数名”形式进行声明,各个参数之间用逗号分开.
5 方法的主体
方法的主体部分就是这个方法实现某一特定功能的代码。自定义方法时,应该先写方法的声明包括访问修饰符,返回值类型,方法名,参数列表,然后写方法的主体.g
1.7注释
我们知道,编写代码时非常重要的一项工作是为代码写注释,而c#的注释和块注释与java是完全相同的 分别使用//和/。。。/但 文档注释与java中的注释有略微不同 C#中使用///而且文档注释的每一行都以///开头
2.0 C#语法快速热身
刚刚我学习了C#中的变量,常量,注释,类和对象,通过console类实现控制台的输入和输出,还学习了使用vs的调试技巧观察程序的执行。
2.1选择结构
我们在生活中经常要面临一些选择,列如,如果计算机坏了,就不能写程序了;如果买彩票中500万元,那就捐200万元给贫困地区建设学校,如果下雨了,就不能去打球了。在编写程序是,也经常要进行条件判断。回想一下;在java中学习了哪几种条件判断结构?有以下几种基本的选择结构 if if-sele,多重if,switch。C#中也有这几种条件判断结构,但是C#switch的用法与写法与java中有所不同.
2.1.1 if结构
语法
if(条件表达式)
{
//代码块
}
else
{
//代码块2
}
if(条件表达式1)
{
//代码块1
}
else if(条件表达式2)
{
//代码块2
}
else if(条件表达式2)
{
//代码块3
}
else
{
//代码块4
}
if(条件表达式)
{
if(条件表达式2)
{
//代码块
}
else
{
//代码块2
}
}
}
else
{
//代码块3
}
2.1.2 switch结构
C#中 switch结构用法与java究竟有哪些不同呢?我们知道,java语言允许case中没有break语句,如果当前执行的case中没有break语句,程序会继续执行下一个case,直到遇到第一个break;语句跳出,或执行完switch结构。还有,紧跟在switch结构后面表达式的值或变量可以为int,short,byte,char 枚举类型,string等数据类型.
c#语言要求每个case和default语句中都必须有break语句,除非两个case中间没有其他语句那么前一个case可以不包括break。另外,c#中的switch判断更加灵活,判断的表达式或变量还可以是字符串类型。
2.2数组与循环
2.2.1 一维数组
语法
数据类型[]数组名;
数据类型 数组名[];
数据类型[]数组名;
通过数组的Length属性,可以获得数组的长度,语法如下
数组名.Length
同java一样,访问数组的元素使用的形式如下,下表从0开始。在c#中我们也把下表叫做索引。
语法如下
数组名[下标]
2.2.2对象数组
为了更方便的保存和操作学员信息,将姓名,成绩封装到学员类中。学习数组时我们已经知道 要保存三个学员姓名可以使用一个string类型的数组,要保存三个学员成绩可以使用一个student类型的数组,此时,数组元素为学员对象,我们之为对象数组。实现代码
2.2.3循环结构
在java只能,我们学习过循环 do-while循环 for循环, 你还记得它们的语法和执行过程么?C#中也有这三种循环结构,而且同java中的语法和执行过程完全一样.除此之外,我们还要介绍一种新的循环结构-foreach。
首先让我们对java中学过的循环结构语法进行简单回顾,而后学习foreach结构。
1.while循环
while循环时先判断条件是否满足,如果条件成立再执行循环体,语法如下
while(条件表达式)
{
//代码块
}
2.do-while循环
do-while循环时先执行再判断的条件,所以至少会执行一次循环体中的语句,语法如下
do
{
//代码块
}while(条件表达式);
3.for循环
for循环常常用再确定循环次数的情况下,
语法如下
for(表达式1;表达式2;表达式3)
{
//代码块
}
-
foreach循环
现在我们要认识一个新朋友–foreach循环。列如 我们去超市买东西付款的时候,要把每一件物品都计价。再入,你再北大青鸟上课,课程中的每一门课都要学习。这些都可以使用循环来描述。each时每个的意思,foreach循环结构用于遍历一个数据集合(目前只学习了数组)的一项,需要设置一个标识符(变量)依次表示其中的每一项。在循环期间,可以对个数据执行指定的操作.
语法
foreach(元素类型 元素变量名 in 数组) { //代码块 }
foreach结构
的执行过程时循环体一次去除数组中的每一个元素,然后对,每个元素都执行一次循环体的操作.
循环应用的区别如下
while循环时先判断条件表达式是否成立。诺成立条件。则执行循环体;否则结束循环.
do-while 循环先执行一次循环体再判断条件表达式是否成立.诺条件成立,则继续循环;否则结束循环.
for循环必须使用整形变量做循环计算器,通过条件表达式限定计数器变量值来控制循环.
foreach循环用于遍历给定数组的所有值.
2.2.4跳转语句
1.break语句
除了再switch结构中可以使用break语句退出某个case语句外,也可以把它用于for,while,do while foreach循环结构 break语句将时程序跳出当前循环结构,并继续执行改循环后的语句。
2.continue语句
continue语句与break语句类似,它出现再for,while,do-while,foreach的循环结构中。但continue语句的作用时退出当前循环结构的本次循环,并开始执行当前循环结构的下一次循环,而不是退出当前循环结构。c#中的break,continue语句的作用与java时相同的.
2.3冒泡排序
2.3.1冒泡排序算法
生活中总会有很多打乱的数字需要我们进行去排序 我们从数组的第一个元素开始,将当前元素同它后面的元素进行比较,每一轮比较懂找到一个最大的数交换到数组的尾部,也就是说大的气泡向后冒.外层循环控制比较多少论,内层循环控制每轮比较多少次。程序的关键时确定内层循环和外层循环循环变量的初始值和终止条件。我们按照循环过程一起来走一扁.
for(i = 0; i < 数组名.Length - 1; i++) { for(j = 0; j<数组名.Length-1-i;j++) { if(数组名[j]>数组名[j+1]) { temp = 数组名[j]; 数组名[j] = 数组名[j+1]; 数组名[j+1] = temp;h } } }
3.0使用属性升级MyBank
3.1Private访问修饰符
3.1.1访问修饰符
在应用中,访问修饰符可以用来修饰类成员字段和方法,以此限定类成员的可访问级别,在java中已经使用过public,现在我们再认识一个新的访问修饰符private(私有的)它们有什么区别呢.
如果将类成员声明为public,就表示这些类成员可以被其他类访问.如果使用private限制类成员的访问权限,那么这些类成员就只能再该类里面使用,其他类对它们没有访问权限.
这与我们到餐馆吃饭的情况相似。任何人都可以在餐馆的餐厅里就餐,但是餐馆的厨房却是重地,所有客人都不得进入,只有餐馆的工作人员才能进入.这种环境下,餐馆的餐厅是public的,厨房则是private的.
c#中访问修饰符
访问修饰符 访问权限 访问级别 public 不受任何限制 最高 private 只有类的内部可以使用 最低
因为Student类的字段_name被定义为private(私有字段),受到保护级别限制,所以在prog类中无法访问Student的私有成员。
如何能使学员类对象与外界进行有效的信息交流呢?
可以在Student类中添加两个public方法int()和say() 其中,int()方法是对创建的学员类对象进行初始化,而Say()方法则是将学员类对象的特征信息提供给其他类。
3.2this关键字
在面向对象的编程语言中,this关键字是指当前对象本身。通过this可以引用当前类的成员变量和方法。如将上面问题中的Student类的SetName()中代码"_name = _name;“改写为"this._name=_name”;
由此可以看出,使用this关键字可以解决成员变量和局部变量名称的冲突问题.
3.3C#属性
3.3.1用方法保证数据安全
using System;
namespace YX3
{
class Student
{
private string _name;
private int _age;
public string _cardID;
public int GetAge()
{
return this._age;
}
public void SetAge(int age)
{
if (age < 0 || age > 100)
{
this._age = 19;
}
else
{
this._age = age;
}
}
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
student.SetAge(-10);
Console.WriteLine("年龄是:{0}", student.GetAge());
student.SetAge(25);
Console.WriteLine("年龄是:{0}",student.GetAge());
Console.ReadLine();
}
}
}
从刚刚的代码可以看出,当把setage()方法参数设置为-10时,程序运行的结果是19.这是因为在SetAge()方法中进行了判断。如果_age的值小于0或大于100,那么就会赋值为19.当SetAge()方法参数设置为25时,程序的输出结果则是25.从输出的解雇哦可以看到问题得到了解决,但是付出的代价时Student类要提供两个公用方法SetAge()和GetAge(),通过SetAge()方法验证用户的输入值是否合法,执行GetAge()方法输出当前对象的年龄.
3.3.2用属性实现字段封装
1.C#的属性
在C#中,字段通常时私有的。如果要访问类中的字段,需要通过get和set访问器实现,这种结合了字段和方法的实现方式我们称之为属性.
语法如下
private string _name;
public string Name
{
get{return _name;}
set{_name = value;}
}
get访问器用来返回相应的私有字段的值。get访问器与方法相似,必须用return语句返回字段的值。执行get访问器相当于读取类中私有字段的值.
set访问器用来设定夏国英的私有字段的值。set访问器类似与返回类型weivoid的方法,它使用一个隐含的输入参数value。当对属性赋值时,将会调用set访问器,并将新的参数值赋予对应的字段
2.属性的数据类型
定义类中的一个属性时,属性的数据类型必须与它所访问的字段类型一致。列如,年龄字段_age时整形,那么,它的属性Age也必须时整形的。如果姓名字段_name为string类型,那么它对应的属性Name也一定时string类型.
3.属性的访问类型
属性出来可以约束数据访问外,还可以设置 读,写属性来限定它的访问类型。属性的访问类分为以下三种
只读属性,只包含get访问器。
只写属性,只包含set访问器。
读写属性,包含get和set访问器。
如果要将一个属性设置为只读属性,即只能读取字段的值而不能给该字段赋值,那么,只需要为这个属性定义get访问器,但不定义set访问器就可以实现。列如,学员姓名字段通常不允许改变,可以设置为只读属性。
同样,如果要将一个属性设置为只写属性,那么只需要指定set访问器即可。列如,按照银行的规定,只允许账户修改自己的密码,但不停供输出操作,这就可以将账户密码设置为只写属性
由此可以看出,get和set访问器的灵活运用,可以保障类中字段的安全。
4.在编码中快速地创建属性
属性在c#开发中的使用时非常普通的,除了手动输入代码外,vs还提供了一个快捷的方法:重构一封装字段。在一个类中,定义一个字段,通常设定为私有,选中这个字段右击.在弹出的快捷菜单中选择"重构"-"封装字段"选项,
选择封装字段选项后vs 会打开一个窗口,可以修改属性的名称,在单机确定按钮后机会将选择的字段与属性建立关系.
5.对象初始化器
在c#中,提供了对象初始化器,可以更方便地为对象的属性赋值如下面的代码
Student student = new Student(){age = -20}
在类中有多个属性时,使用对象初始化器可以同时为多个属性赋值。多个属性之间用逗号间隔,使用{}封闭
3.3.3面向对象的特征—封装
顾名思义,封装表示将东西打包,使其以新的完整的形式出现。
在面向对象编程中,封装可以理解为将数据和操作方法保存在一起的技术,或是有选择地隐藏或公开类中的属性和方法的过程。封装的具体实现是将成员变量,方法和属性以类的形式进行封装,在类或对象的之间通过消息传递进行相互交流,而传递消息是通过调用类公开的方法完成的.
3.4值传递和引用传递
还记得在java中怎样将数据传递给方法吗?通过参数把值传递给方法。现在,让我们看看在C#中又是如何传递参数的]
3.4.1值传递
using System;
namespace YX5
{
class pay
{
public void Intpupay()
{
int pay;
float taxRate = 0.15f;
float afterTax;
Console.WriteLine("请输入税前工资:");
pay = int.Parse(Console.ReadLine());
afterTax = GetPay(pay, taxRate);
Console.WriteLine("税前工资{0},税后工资{1}", pay, afterTax);
}
public float GetPay(int pay, float taxRate)
{
float afterTax;
if (pay <= 3500)
{
afterTax = pay;
}
else
{
afterTax = pay - (pay - 3500) * taxRate;
}
return afterTax;
}
}
class Program
{
static void Main(string[] args)
{
pay pay = new pay();
pay.Intpupay();
}
}
}
如上面代码中,首先创建yx5类对象pay 然后用pay对象调用inputpay()方法。在inputpay()方法中从控制台接收税前工资后,调用GeyPay()方法计算税后工资…
4.0深入C#的string类
字符串是应用程序中最常用的一种数据类型。在java课程中我们已经学习过java语言的字符串处理方法,C#中也有一个专门处理字符串的类string,它位于system命名空间捉弄。我们一直使用的string 只不过是string 类的一个别名。就好比你有一个名i在,到哪里都能用,但是在你们班,同学们又给你起了一个外号,在班里,同学们叫你的名字或外号所得到的效果都是一样的,但是在校外就没人知道你的外号。string就是string在C#中的外号,在C#中二者的使用是完全一样的。现在就让我们来认识强大的string类.
4.1.1常用的字符串处理方法
C#中提供了比较丰富丶1字符串处理方法。下面就列出了一些常用的方法及每个方法接受的参数和返回值.
方法 | 说明 |
---|---|
bool Equals(stinrg value) | 比较一个字符产与另一个字符串value的值是否相等。若二者相等,则返回true诺不相等,则返回False |
int Compare(string strA,string strB) | 比较两个字符串的大小关系,返回一个整数。若strA小于strB,则返回值小于0若strA 等于 strB 则返回值为0;若strA 大于strB,则返回值大于0 |
int IndexOf(sting value) | 获取指定位置的字符串在当前字符串中第一给匹配项的位置。如果找到了就返回它的位置;如果没有找到,就返回-1 |
string join(string separator,string[] value) | 获取指定我的字符串value在当前字符串最后一个匹配项的位置。如果找到了value就返回它的位置;如果没有找到,就返回-1 |
string[]Split(Char separator) | 把字符串数组value在当前字符串用指定的分割符separator连接,返回连接后的字符串 |
string Substring(int startIndex,int length) | 从指定的位置startIndex开始检索长度为Length子字符串 |
string ToLower() | 获得字符串的小写形式 |
string ToUpper() | 获得字符产的大写形式 |
string Trim() | 去掉字符串前后两端多余的空格 |
4.1.2连接分割字符串
上文中使用的几种字符串处理方法在java中东用过,你一定很熟悉了。现在来看看string类另外两个常用的方法join()和split()方法。它们的功能分别是连接和分割字符串,这两个方法应该怎么使用呢?
class Program
{
static void Main(string [ ] args)
{
string inputString;
string[] splitString;
string joinString;
Console.WriteLine("请输入一串字符串,用空格分隔单词:");
inputString = console.ReadLine();
splitStrings = inputString.Split('');
console.writeLine("\n分割后的字符串为:");
foreach(string s in splitString)
{
console.writeLine(s);
}
joinString = string.Join("_",splitStrings);
console.writeLine("\n连接后的新字符串为:{0}",joinString);
}
}
在上面代码中 语句 splitStrings = intputString.Split(’ ');将字符串对象inputString的值按空格 分割为多个字符串,并通过赋值运算符将这些子字符产作为方法Split()的返回值保存在数组splitString中。为将多给字符串连接起来,代码调用了join()方法。注意:join()方法是String 类的静态方法,要以string类名来调用,这点与Split()方法不同。
4.1.4Format格式化
语法
string myString = String.Format("格式字符串",参数列表);
其中,格式字符串中包含固定文本和格式项。格式项形式如下所示。
{索引[,对齐][:格式字符串]}
其中,索引从0开始,与变量列表对应;对齐部分设置显示的宽度和对齐的方式,是一个带符号整数,整数的大小表示数据的宽度,正数为右对齐,负数为左对齐;格式字符串部分包含格式说明符。
格式化数值结果表
字符 | 说明 | 示列 | 输出结果 |
---|---|---|---|
C | 货币格式 | String.Format("{0:C3}",2000) | ¥2000.000 |
D | 十进制格式 | String.Format("{0:D3}",2000) | 2000 |
F | 小数点后的位数固定 | String.Format("{0:F3}",2000) | 2000.000 |
N | 用逗号隔开的数字 | String.Format("{0:N}",25000) | 250,000 |
P | 百分比计数法 | String.Format("{0:P3}",0.29768) | 29.768 |
X | 十六进制格式 | String.Format("{0:X000}",12) | C |
4.2.3使用Convert类进行转换
我们知道Parse()方法可以将字符串类型转换为数值类型,其实C#中还有一个更全年的类-Convert类,它可以在各种基本类型之间执行数据类型的互相转换。Convert类为每种类型转换都提供了一个对应的方法,Convert类常用的方法
常用Convert类的类型转换方法
方法 | 说明 |
---|---|
Convert.ToInt32() | 转换为整型(int 型) |
Convert.ToSingle() | 转换为单精度浮点型(float型) |
Convert.ToDouble() | 转换为双精度浮点型(double型) |
Convert.ToString() | 转换为字符串类型(string 型) |
隐式类型转换:常用于数值型之间,将取值范围小的数值类型转换为取值范围大的数值类型.