C#编程语言基础
一、C#语言的基本介绍
1.1 .NET与C#
1.1.1 .NET概述与C#应用
.NET是Microsoft.NET的简称,是基于Windows平台的一种技术。它包含了能在.NET Framework平台运行的所有编程语言。这一次我们主要了解的是C#语言。
1.1.2 IDE环境
微软推出了强大的平台和技术,并提供了强大的集成开发环境(IDE)来支持,这就是Visual Studio,它集成了.NET Framework,是目前最流行的.NET平台开发环境。需要注意的是Visual Studio的运行必须在本地拥有相匹配.NET Framework环境。
1.2 C#程序的创建
1.2.1 新建程序
在使用Visual Studio时的创建与Java不同,分别是:
- 启动visual studio
- 新建项目
- 生成可执行文件
- 开始运行
在“新建项目”中可以看到有许多的项目模板,这里我们选择“控制台应用程序”这一选项。在C#中多了一个容器,即“解决方案”。在解决方案中可以包含一个或多个项目。其中扩展名为.cs的文件是该项目的启动文件。
1.2.2 认识C#程序的结构
示例1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HellowWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hellow World"); //输出Hellow World
Console.ReadLine();
}
}
对于这一段程序,看起来与Java有几分相似,下面我们就来了解一下这个程序的各个组成。
1.namespa关键字
namespa(命名空间)是C#中组织代码的方式,它的作用类似于java中的packa包,这样我们就可以把紧密相关的一些代码发在同一个命名空间中,大大挺高了管理和使用效率。
2.using关键字
在Java中如果导入其他包,应该使用import关键字,而在C#中,使用using关键字来引用其它命名空间,它的作用和Java中的import类似。
3.class关键字
与Java一样,C#也是一种面向对象的语言,使用class关键字表示类,我们编程的代码都应该保存子啊一个类里面,类要包含在一个命名空间里面。
4.Main()方法
C#中的Mian()方法和Java中的main方法的作用是一样的,但是程序的入口,应用程序从这里开始运行,但要注意的是C#中的Main()方法m要大写,Main()方法的返回值可以是void或者int类型,Mian()方法可以没有命令行参数。
C#中Main()方法的四种写法:
语法
static void Main(string [] args){}
static void Main(){}
static int Main(string [] args){}
static int Main(){}
5.关键代码
在Main()方法中的两行代码就是用来输入和输出。
Console.WriteLine("Hellow World"); //从控制台输出内容
Console.ReadLine(); //从控制台输入内容
1.3 C#中的变量和常量
1.3.1 C#中的数据类型
每一种语言都有它的数据类型,C#语言的数据也与Java中的数据类型有相似,又有着区别。下列列举的是最常用的数据类型。
C#常用的数据类型
常用数据类型 | Java | C# | 举 例 |
---|---|---|---|
整型 | int | int | 年龄 |
浮点型 | float | float | 成绩 |
双精度型 | double | double | 圆周率 |
字符串型 | String | string | 姓名 |
布尔型 | boolean | bool | 是否是少数名族 |
需要注意的是C#中在为浮点型变量赋值时,数据必须以字母f或F结束。
1.3.2 C#中的变量
C#中的变量声明方式与Java是相同的。
语法
数据类型 变量名称;
C#中的变量命名规则与Java也基本相同,只是"$"符号在C#中不能使用,因此命名规则可以简单总结为以下三条:
组成:52个英文字母(AZ,az),10个数字(0~9),下划线(_),除此之外不能含有其它字母。
开头:只能以字母或下划线开头。
不能使用的:不能是C#中的关键字。
1.3.3 C#中的常量
在C#中调用值时不免会遇到赋值错误的情况,这时就需要定义常量来解决这个问题。
1.常量含义:
常量计算在程序运行过程中保持不变的值。
语法
const 数据类型常量名称 = 值;
示例2
namespace yx3
{
class Program
{
static void Main(string[] args)
{
const double pi = 3.1415926; //定义一个常量pi
int r = 5;
//计算圆的周长
double girth = 2 * pi * r;
//计算圆的面积
double area = pi * r * r;
Console.Write("圆的周长是 :");
Console.WriteLine(girth);
//输出圆的周长
Console.Write("圆的面积是:");
Console.WriteLine(area);
//输出圆的面积
Console.ReadLine();
}
}
}
2.常量命名规范
- 常量名称必须具有一定的意义。
- 常量名称最好以大写字母来命名,中间可以根据意义的连接性用做下划线做连接,每个常量定义的右侧做好有简单的注释,说明其作用。
- 常量名称长度最好不要超过25个字符,否则可读性差。
namespace yx2
{
class Program
{
static void Main(string[] args)
{
int daymax =7;
int today =1;
Console.WriteLine("一周有几天:");
Console.WriteLine(daymax);
Console.WriteLine("今天是周:");
today = today + 1;
Console.WriteLine(daymax);
}
}
}
1.4 Console类
1.4.1 C#向控制台输出
在C#中向控制台输出有三种方式。
方式一:
Console.WriteLine();
方式二:
Console.WriteLine(要输出的值)
方式三:
Console.WriteLine("格式字符串",变量列表)
方式三是C#语言中的新语法,用法如下列示例3。
示例3
namespace yx4
{
class Program
{
static void Main(string[] args)
{
string course = "c#";
Console.WriteLine(course);
Console.WriteLine("我的课程名称是:" + course); //用+号输出
Console.WriteLine("我的课程名称是:{0}", course); //用占位符输出
}
}
}
C#向控制台读入
语法
1.4.2 C#向控制台读入
语法
Console.ReadLine();
如果需要输入整形数据,使用如下方法进行强转。
int age=int.Parse(Console.ReadLine());
1.5 类和对象
1.5.1 创建类和对象
C#中的自定义方法以及类的创建基本上和Java是一样的。
语法
{访问修饰符 返回值类型 方法名(参数列表)}
{
//方法的主体
}
语法
{访问修饰符} class 类名
{
//类的主体
}
需要注意的是以下几点:
1.访问修饰符
public (公开的)
private(私有的)
protected(受保护的)
internal(默认的)
2.方法的返回值类型
我们编写的方法是实现特定功能的模块,课供他人使用,在调用后可以有一个返回值,这个返回值的数据类型就是返回值的数据类型。
3.方法名
每个自定义的方法都有一个名称,方法的名称应具有明确的含义,这样别人使用的时候就能清楚的知道这个方法能实现什么功能了。
4.参数列表
调用方法时,可以向方法中传递参数,这些参数构成了参数列表,如果没有参数就不要oyng参数列表,参数列表中的每个参数都是通过”类型参数名“。
5.方法的主体
方法的主体部分就是这个方法实现某一些特定功能的代码,自定义方法时,应该先写方法的声明,包括访问修饰符,返回值类型,方法名,参数列表,然后写方法的主体。
示例
namespace yx6
{
public class Student
{
public string name;
public int age;
public void show()
{
Console.WriteLine("学员姓名:{0},年龄:{1}," ,name, age);
}
}
class Program
{
static void Main(string[] args)
{
Student stu = new Student();
Console.WriteLine("请输入姓名:");
stu.name = Console.ReadLine();
Console.WriteLine("请输入年龄:");
stu.show();
}
}
}
1.5.2 注释
单行注释//内容
块注释
/*
*内容
*/
文档注释
///
///说明
///
折叠注释
#region
#endregion
namespace yx7
{
public class Student
{
#region 成员变量
//学员姓名
public string name;
//学员年龄
public int age;
#endregion
#region 显示学员姓名和年龄信息
///<summary>
///输出学员姓名和年龄
///</summary>
public void show()
{
Console.WriteLine("学员姓名:{0},年龄:{1}", name, age);
}
#endregion
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
Console.WriteLine("请输入姓名:");
student.name = Console.ReadLine();
Console.WriteLine("请输入年龄:");
student.age = int.Parse(Console.ReadLine());
student.show(); //显示学员信息
Console.ReadLine();
}
}
}
二、C#语法
2.1 选择结构
2.1.1 if选择结构
if选择结构:
语法
if(条件表达式)
{
//代码块
}
C#中的if–else结构:
语法
if(条件表达式)
{
//代码块1
}
else
{
//代码块2
}
C#中的多重if结构:
语法
if(条件表达式1)
{
//代码块1
}
else if(条件表达式2)
{
//代码块2
}
else if(条件表达式3)
{
//代码块3
}
else
{
//代码块4
}
C#中的嵌套if结构
语法
if(条件表达式1)
{
if(条件表达式2)
{
//代码块1
}
else
{
//代码块2
}
else
{
//代码块3
}
在C#中与java if选择结构的语法是一样的,但是需要注意:
1.只有当满足外层if的条件时,才会判断内层if的条件
2.else与离他最近的那个缺少else的if相匹配
2.1.2 switch选择结构
C#中的语言要求每个case和default语句中都必须要有break语句,除非两个case中间没有其它语句,那么前一个case可以不包含break。
C#中的switch结构
语法
switch(表达式)
{
case 常量1:
//代码块
break; //必须有
}
java中的switch结构
语法
switch(表达式)
{
case 常量1:
break; //可有可无
}
示例4
namespace yx1
{
///<summary>
///通过银行简称来输出银行全称
///</summary>
///
///<summary>
///根据从控制台输入的简称来输出银行全称
///</summary>
class Fullbank
{
public void Bankname()
{
Console.WriteLine("请输入银行简称:");
string bank = Console.ReadLine().ToUpper();
//将银行的简称转换为大写字母
switch (bank)
{
case "ICBC":
Console.WriteLine("中国工商银行");
break;
case "CBC":
Console.WriteLine("中国建设银行");
break;
case "ABC":
Console.WriteLine("中国农业银行");
break;
default:
Console.WriteLine("输入银行简称错误!");
break;
}
}
class Program
{
static void Main(string[] args)
{
Fullbank bank = new Fullbank();
bank.Bankname();
}
}
}
2.2数组
1.C#中数组:
语法
数据类型[] 数组名 = new 数据类型[长度];
数据类型[] 数组名 = {};
数据类型[] 数组名 = new 数据类型[长度]{};
int[] array4 = new int[3] { 1, 2, 3 };
示例5
namespace yx3
{
class Program
{
static void Main(string[] args)
{
int [] arrays=new int[5] { 0,1,2,3,4};
//创建一个含有五个整形数组的数组
int[] arr1 = new int[] { 0,1,2,3,4};
//省略数组长度
int[] arr2 = { 0, 1, 2, 3, 4 };
//省略new关键字
Console.WriteLine("数组array的元素个数是{0}", arrays.Length);
Console.WriteLine("数组arr1的元素个数是{0}", arr1.Length);
Console.WriteLine("数组arr2的元素个数是{0}", arr2.Length);
}
}
}
2.获得数组的长度:
语法
数组名.Length
3.访问数组的元素:
语法
数组名[下标]
4.对象数组:
示例6
namespace yx4
{
//学员类
public class Student
{
public string name;
public double score;
public void showInfo()
{
//输出信息
Console.WriteLine(name + "\t" + score);
}
}
class Program
{
static void Main(string[] args)
{
//定义对象数组
Student[] stus = new Student[3];
//给对象数组赋值
stus[0] = new Student();
stus[0].name = "张浩";
stus[0].score = 100;
stus[1] = new Student();
stus[1].name = "李晨";
stus[1].score = 99;
stus[2] = new Student();
stus[2].name = "江宜";
stus[2].score = 95;
Console.WriteLine("前三名的信息为:");
foreach (Student stu in stus)
{
stu.showInfo();
}
Console.WriteLine();
}
}
}
2.3.循环结构
1.while结构
语法
while(条件)
{
//代码块
}
2.do-while 循环
语法
do
{
//代码块
}while(条件);
3.for循环
语法
for(初始化; 条件;迭代)
{
//代码块
}
示例7
namespace yx5
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[5] { 0, 1, 2, 3, 4 };
Console.Write("数组array中{0}个元素的值是:", array.Length);
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i] + " ");
}
Console.WriteLine();
Console.ReadLine();
}
}
}
4.foreach循环
语法
foreach(数据类型[根据数组的数据类型决定] 变量名 in 数组名)
{
//代码块
}
示例8
namespace yx6
{
class Program
{
static void Main(string[] args)
{
int[] arrray = new int[5] { 0, 1, 2, 3, 4 };
//循环中将array的每个元素赋值给item
Console.Write("数组array中给{0}元素的值是:", arrray.Length);
foreach(int item in arrray)
{
Console.Write(item + " ");
}
Console.WriteLine();
Console.ReadLine();
}
}
}
三、C#中访问修饰符与属性与传递
3.1 C#中的访问修饰符
在应用程序中,访问修饰符可以用来修饰成员字段和方法,以此类成员的可访问级别,在Java中经常使用public(公共的),现在我们在认识一个新的访问修饰符private(私有的)。
C#中的访问修饰符
访问修饰符 | 访问权限 | 访问级别 |
---|---|---|
public | 不受任何限制 | 最高 |
private | 只有类的内部可以使用 | 最低 |
示例9
namespace yx1
{
class Student
{
//private string _name; //姓名
public string _naem;
public int _age = 19; //年龄
public string _carID = "11089775753243"; //身份证
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
// 无法访问 student._name = "灰太狼";
student._naem= "灰太狼";
Console.WriteLine(student._naem+",今年19岁");
}
}
}
3.2 this关键字
在面向对象的编程语言中,this关键字是指当前对象本身。通过this可以引用当前类的成员变量和方法,简单来说就是引用当前类的对象,使用this关键字可以解决成员变量和局部变量的名称冲突。
示例10
namespace yx2
{
public class Student
{
public string _name ="灰太狼"; //姓名
public int _age = 19; //年龄
public string _carID = "11089775753243"; //身份证
//初始化学员的姓名
public void SetName(string _name)
{
this._name = _name;
}
//输出学员的姓名,年龄
public void Say()
{
Console.WriteLine("大家好!我叫{0},今年{1}岁.",this._name,this._age);
}
}
class Program
{
static void Main(string[] args)
{
Student scc = new Student();
scc.Say();
}
}
}
3.3 用属性实现字段封装
1.C#属性
在C#中,字段通常都是私有的,如果要访问类中的字段,要通过get和set访问器实现,这种结合了字段和方法的实现方式我们称之为属性(property)。
语法
private string _name
public string Name
{
get{ return _name;}
set{ _naem = value;}
}
示例11
namespace yx4
{
public class Student
{
private string _name="灰太狼"; //姓名
private int _age; //年龄
public string _cardID; //身份证号码
public int Age
{
get
{
return _age;
}
set
{
if (value < 0 || value > 100)
{
_age = 19;
}
else
{
_age = value;
}
}
}
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
//执行Age属性的set访问器代码
student.Age = -20;
//执行Age属性的get访问器代码
Console.WriteLine("年龄是{0}",student.Age);
student.Age = 40;
Console.WriteLine("年龄是{0}",student.Age);
}
}
}
2.属性的数据类型
- 定义一个类中的属性时,属性的数据类型必须与它所访问的字段类型一致。
- 属性的类型也可以时一个类或数组。
3.属性的访问类型
属性除了开始约束数据类型外,还可以设置读,写属性来限定它的访问类型,属性的访问类分为以下三种:
- 只读属性,只包含get访问器。
- 只写属性,只包含set访问器。
- 读写属性,只包含get和set。
如果要将一个属性设置为只写属性,那么只要指定set访问器即可,同理,只读和读写属性都可以这样设置
4.在编码中快速的创建属性
属性在C#开发中的使用是非常普遍的,除了手动之外还可以使用快捷键Ctrl+R,E。
5.对象初始器
在C#中,提供了对象初始化器,可以更方便的为对象赋值,如下代码
示例12
Student student=new Studen(){Age=-20};
3.4 值传递和引用传递
3.4.1 值传递
1.基本数据类型:
形参所做修改不会影响实参。
2.引用数据类型:
形参对具体值的修改会影响实参。
如果形参修改了指向的地址,那么接下来形参做的任何一项改变都不会影响实参。
示例13
namespace yx5
{
public class Pay
{
public void Inputpay()
{
int pay; //税前工资
float taxRate = 0.15f; //税率
float afterTax; //税后工资
Console.WriteLine("请输入税前工资(元):");
pay = int.Parse(Console.ReadLine());
//调用方法计算税后工资
afterTax = Getype(pay, taxRate);
Console.WriteLine("税前工资{0},税后工资{1}", pay, afterTax);
}
//根据税率,计算得到税后的工资
public float Getype(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 pays = new Pay();
pays.Inputpay();
}
}
}
3.4.2 按引用传递参数
引用传递(地址传递):
形参所做修改会影响实参。
在实参和形参前面多了一个关键字:ref来修饰参数即可传递。
示例14
namespace yx6
{
class Program
{
static void Main(string[] args)
{
int num1, num2;
Console.WriteLine("请输入两个数字:");
num1 = int.Parse(Console.ReadLine());
num2 = int.Parse(Console.ReadLine());
Console.WriteLine("交换前两个数分别为:{0}和{1}", num1, num2);
//交换两个数的值
Swap(ref num1, ref num2);
Console.WriteLine("交换前两个数后分别为:{0}和{1}", num1, num2);
}
//交换两个数后的方法
public static void Swap(ref int num1, ref int num2)
{
int temp; //中间变量
temp = num1;
num1 = num2;
num2 = temp;
}
}
}
四、深入了解C#的String类
4.1 C#的String类
其中String是:class ,也就是一个类。
别名:string(关键字)。
常用字符串处理方法
方法 | 说明 |
---|---|
Equals():比较值(堆) | 比较一个字符串与另一个字符串value的值是否相等 |
static IsNullOrEmpty(String) | 既可以判断空对象的字符串,又可以判断长度为0的字符串 |
static String.Join(连接符号, 要被连接的数字); | 把字符串数组value中的每个字符串用指定的分隔符连接 |
Split(char“指定的字符”): | 以指定字符串拆分 |
IndexOf(string) | 从前往后找 |
LastIndexOf(string) | 从后往前找 |
Remove(开始下标); | 从开始下标到length-1的内容都被删除 |
ToLower()转换为小写 | 转换为小写 |
toUpper() | 转换为大写 |
Trim() | 去掉前后空格 |
示例15
namespace ConsoleApp1
{
/// <summary>
/// 字符串的处理
/// </summary>
class Program
{
//接收用户邮箱并提取用户名
private void PickNameFromEmail()
{
string email; //邮箱地址
string name; //邮箱用户名
Console.WriteLine("请输入你的邮箱地址:");
email = Console.ReadLine();
Console.WriteLine("你的邮箱地址是:{0}",email);
//提取邮箱中的用户名
int position = email.IndexOf("@"); //获取@的位置
if (position>0)
{
name = email.Substring(0, position); //得到邮箱的用户名
Console.WriteLine("你的邮箱用户名是:{0}",name);
}
else
{
Console.WriteLine("你的邮箱格式错误!");
}
}
//提取用户名邮箱的名称
public void GetUserName()
{
string choice;
do
{
this.PickNameFromEmail(); //调用提取邮箱用户名方法
Console.WriteLine("是否要继续?yes/no");
choice = Console.ReadLine();
choice = choice.Trim().ToLower(); //将英文字母强制转换为小写
} while (choice.Equals("yes")); //判断用户输入的字符是否是yes
}
static void Main(string[] args)
{
Program scc = new Program();
scc.GetUserName();
}
}
}
注意:
-
运算“==”和Equals()方法:
运算符“==”和Equals方法应用于两个字符串,所判断的内容都是有差别的。
-
“ ”和string.Empty:
" ":为string对象分配一个长度为零的空间。
string.Empty:表示空字符串,不会为对象分配存储空间。
在C#中,大多数情况下“ ”和string.Empty可以互换使用,一般建议使用后者。
4.2 Format格式化
C#中的String类提供的一个Format()方法对输出的字符串进行格式化。Format()方法允许把字符串,数字或布尔值类型的变量插入到格式字符串当中,它的语法和WriteLine()方法很相似。
语法
String mystring =String.Format(“格式字符串”,参数列表)
其中,格式字符串中包含固定文本和格式项。
语法
{索引 [, 对齐] [: 格式字符串]}
4.3 类型转换
隐式:自动转换
示例16
int b = 1;
long a = b;
显示:强制转换
4.3.1 Parse()方法
数据类型.Parse(值);
1.字符串转换为数值型
int.Parse(console.ReadLine())
2.将字符串转为整型
int.Parse(string)
3.将字符串转为单精度浮点型
float.parse(string)
4.将字符串转为双精度浮点型
double.Parse(string)
4.3.2 Convert类进行转换
常用Convert类的类型转换方法
方法 | 说明 |
---|---|
Convert.ToInt32() | 换为整型(int型) |
Convert.ToSingle() | 转为单精度浮点型(float型) |
Convert.ToDouble() | 转为双精度浮点型(double型) |
Convert.ToString() | 转为字符串类型(String型) |
这两个方法中Convert类的转换全面,而Parse()方法只能把字符串转换为数字。
字符串,所判断的内容都是有差别的。
-
“ ”和string.Empty:
" ":为string对象分配一个长度为零的空间。
string.Empty:表示空字符串,不会为对象分配存储空间。
在C#中,大多数情况下“ ”和string.Empty可以互换使用,一般建议使用后者。
4.2 Format格式化
C#中的String类提供的一个Format()方法对输出的字符串进行格式化。Format()方法允许把字符串,数字或布尔值类型的变量插入到格式字符串当中,它的语法和WriteLine()方法很相似。
语法
String mystring =String.Format(“格式字符串”,参数列表)
其中,格式字符串中包含固定文本和格式项。
语法
{索引 [, 对齐] [: 格式字符串]}
4.3 类型转换
隐式:自动转换
示例16
int b = 1;
long a = b;
显示:强制转换
4.3.1 Parse()方法
数据类型.Parse(值);
1.字符串转换为数值型
int.Parse(console.ReadLine())
2.将字符串转为整型
int.Parse(string)
3.将字符串转为单精度浮点型
float.parse(string)
4.将字符串转为双精度浮点型
double.Parse(string)
4.3.2 Convert类进行转换
常用Convert类的类型转换方法
方法 | 说明 |
---|---|
Convert.ToInt32() | 换为整型(int型) |
Convert.ToSingle() | 转为单精度浮点型(float型) |
Convert.ToDouble() | 转为双精度浮点型(double型) |
Convert.ToString() | 转为字符串类型(String型) |
这两个方法中Convert类的转换全面,而Parse()方法只能把字符串转换为数字。