菜鸟先飞C#学习总结(一)
一、第一个程序Hellow Word
using System; //using 关键字用于在程序中包含 System 命名空间。 一个程序一般有多个 using 语句。
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Helloword
{
class Program //声明一个类
{
static void Main(string[] args) // Main 方法,是所有 C# 程序的 入口点。Main 方法说明当执行时 类将做什么动作。
{
Console.WriteLine("Hello Word!");
Console.ReadKey();
}
}
}
二、C#数据类型
- 值类型(Value types)
- 引用类型(Reference types)
- 指针类型(Pointer types)
(一)值类型
就是那些 float,char,int啊之类的数据类型,具体的类型:
(二)引用类型
引用类型主要包含三种:动态类型,字符串类型和对象类型
引用类型的变量持有的是数据的引用,数据存储在数据堆,分配在托管堆中,变量并不会在创建它们的方法结束时释放内存,它们所占用的内存会被CLR中的垃圾回收机制释放。
1.动态(dynamic)类型
存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。也就是我可以定义一个动态类型的变量,然后只有执行的时候我才知道这个定义的变量是什么类型的。
什么时候用到这个类型呢?
在Coding中有时候会遇到一些需要解析的数据,可是数据的字段数量和名称未统一,我们没法定义实体类来对应。那么我们就会想到通过C#的dynamic动态类来实现,如果大家注意的话一些ORM框架里面貌似都有用到dynamic来实现一部分功能。
动态类型的基本应用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 数据类型
{
class Program
{
static void Main(string[] args)
{
//引用类型
dynamic x =;
//获取x的数据类型
Type ty = x.GetType();
dynamic y = "name";
Type ty1 = y.GetType();
//打印出上边未知的数据类型
Console.WriteLine(ty.ToString());
Console.WriteLine(ty1.ToString());
Console.ReadKey();
}
}
}
想了解更多关于dynamic类型:http://www.cnblogs.com/FourLeafCloverZc/p/4348722.html
2.对象(object)类型
对象(Object)类型 是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。
这种类型的转换就是常说的拆箱和装箱。
当是值类型转化成对象类型的时候就是装箱,当对象类型转化成值类型就是拆箱。装箱是隐式的;拆箱必定是显式的。
1.装箱
object ob;
obj = ;
2.拆箱
object obj = ;
int x = int(obj);
为什么要关注装箱和拆箱呢?装箱是需要占用资源的(cpu,内存等等),而在日常编码中,经常有装箱与拆箱的操作,而且这些装箱与拆箱的操作往往是在不经意时发生,装箱更加的占用资源,这不难理解,因为引用对象的分配更加复杂,成本也更高,值类型分配在栈上,分配和释放的效率都很高。装箱过程是需要创建一个新的引用类型对象实例,拆箱过程需要创建一个值类型字段,开销更低。为了尽量避免这种性能损失,尽量使用泛型,在代码编写中也尽量避免隐式装箱。
PS:如果想了解更多拆箱,装箱:http://www.cnblogs.com/anding/p/5236739.html
3.字符串(String)类型
string firstCode = "Hellow Word!";
在C#中,string 是 System.String 的别名,所以基本上在使用时是没有差别的。习惯上,我们把字符串当作对象时(有值的对象实体),我们用string。而我们把它当类时(需要字符串类中定义的方法),我们用String,
比如:string greet = String.Format("Hello {0}!", place);其实乱用也可以,只是这样概念上清楚一点。另外string是C#保留字,不可用作变量名,String就不是了。如果深入详解,String是.net framework平台中通用类型(CTS)的数据类型,而string是开发环境vs从String
类型映射过来的数据类型,无论是他们之中的他一个,在编译后转换成的中间语言(IL)都将是一样的.
三、类和结构
(一) 访问修饰类型
public | 公有访问。不受任何限制。 |
private | 私有访问。只限于本类成员访问,子类,实例都不能访问。 |
protected | 保护访问。只限于本类和子类访问,实例不能访问。 |
internal | 内部访问。只限于本项目内访问,其他不能访问。 |
protected internal | 内部保护访问。只限于本项目或是子类访问,其他不能访问 |
(二)
- 类
类和结构是创建对象的模板,类定义了每个类对象包含的数据和功能。比如说一个顾客表示一个类。那么这个类里面可以包含顾客的姓名,年龄,身高等信息。我们可以实例化这个类,用来表示这个顾客。
Class CustomersClass{
public const string activDay= "Friday";
public int CustomerID;
public int age;
public string Name;
}
- 结构
结构与类的写法相似,struct 关键字用于创建结构体:
struct CustomersStruct{
public const string activDay= "Friday";
public int CustomerID;
public int age;
public string Name;
}
类和结构的区别:
- 类是引用类型,类是存储在堆中的;结构是值类型,存储在栈中。
- 结构不支持继承
- 较小的数据类型使用结构可以提高性能。
- 结构不能声明默认的构造函数。
- 结构体中声明的字段无法赋予初值,类可以
- 结构体的构造函数中,必须为结构体所有字段赋值,类的构造函数无此限制:
结构体和类应用场景:
- 当堆栈的空间很有限,且有大量的逻辑对象时,创建类要比创建结构好一些;
- 对于点、矩形和颜色这样的轻量对象,假如要声明一个含有许多个颜色对象的数组,则CLR需要为每个对象分配内存,在这种情况下,使用结构的成本较低;
- 在表现抽象和多级别的对象层次时,类是最好的选择,因为结构不支持继承。
- 大多数情况下,目标类型只是含有一些数据,或者以数据为主。
类和结构实例化:
CustomersClass customers1 = new CustomersClass();
CustomersStruct customers2 = new CustomersStruct();
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 访问修饰符
{
class Customers
{
public const int birth = ;
public int CustomerID;
public string name;
public float height;
//public 可以在对类进行实例化之后进行调用
public int Buy(int money, int number)
{
return money * number;
}
//private 表示的是该方法只能在类内使用,无法在另一个类当中调用,否则就会出现错误
private String action()
{
return "测试函数"; }
}
//可以将struct换成是class
struct Customers1
{
public const int birth = ;
public int CustomerID;
public string name;
public float height;
int age; public int AGE() {
//age 无法在类外使用但是可以在类内使用,在这里对私有成员 age进行赋值,通过公有函数返回值可以通过实例化获取。
age = ;
return age;
}
}
class Program
{
static void Main(string[] args)
{
//实例化
Customers1 c1 = new Customers1(); //由于Customers1是私有属性,所以无法访问类和类中的成员
c1.CustomerID = ;
c1.name = "小明";
c1.height = 165.8F;
// c1.age = 30; //类成员默认是私有的,只能类的内部使用,类外无法获取,会报错误 Console.WriteLine(c1.AGE()); //age 无法在类外使用但是可以在类内使用
Customers c = new Customers();
c.CustomerID = ;
c.name = "梦";
c.height = 156.8F;
Console.WriteLine(c1.CustomerID);
Console.WriteLine(c.CustomerID);
Console.WriteLine("请输入价格:");
int money =Convert.ToInt32(Console.ReadLine());
Console.WriteLine("请输入数量:");
int number = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("总价是:{0}", c.Buy(money, number));
Console.ReadKey();
// c.action(); //这里会显示错误“不可访问,因为他受到保护级别限制” }
}
}
四、类成员
类的成员包含数据成员和函数成员。
class Customers
{
//数据成员
public const int birth = ;
public int CustomerID;
public string name;
public float height; //函数成员,函数成员包括:方法,属性,构造函数,终结器,索引器,运算符
//public 可以在对类进行实例化之后进行调用
public int Buy(int money, int number)
{
return money * number;
}
//private 表示的是该方法只能在类内使用,无法在另一个类当中调用,否则就会出现错误
private String action()
{
return "测试函数"; }
}
(一)方法
1.方法声明
修饰词 返回类型 方法名(参数列表){
//方法体;
}
例如:
//有返回值
public int Buy(int money, int number){
//返回值
return money* number;
}
//没有返回值
public void Buy(){
//返回值
int x = 15;
}
2.方法的调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 访问修饰符
{ class Customers
{
public const int birth = ;
public int CustomerID;
public string name;
public float height;
//public 可以在对类进行实例化之后进行调用
public int Buy(int money, int number)
{
return money * number;
}
public static int Buy1(int money, int number){
return money * number;
}
}class Program
{
static void Main(string[] args)
{
Customers c = new Customers();
c.CustomerID = ;
c.name = "梦";
c.height = 156.8F; Console.WriteLine("请输入价格:");
int money =Convert.ToInt32(Console.ReadLine());
Console.WriteLine("请输入数量:");
int number = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("总价是1:{0}", c.Buy(money, number)); //没有使用static修饰方法,可以使用实例化名称来调用
Console.WriteLine("总价是2:{0}",Customers.Buy1(money, number)); //使用static修饰方法之后,需要用类名来调用,不能使用实例化名称调用
Console.ReadKey();
// c.action(); //这里会显示错误“不可访问,因为他受到保护级别限制” }
}
}
3.方法传参
在成员方法中几乎所有的参数都是通过值传递,除非特别声明
值传递和引用传递:
- 值传递
方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
- 引用传递
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
//这里交换的只是将i和j的值用副本传递给了change,i和j本身没有变化,所以值并没有发生变化
public class TestValue {
public static void main(String[] args) {
int i = ;
int j = ;
change(i,j);
System.out.println(i);
System.out.println(j);
}
public static void change(int i,int j){
int temp = i;
i = j;
j = temp;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 值传递和引用传递1
{
class Student
{
private float score;
public Student(float score)
{
this.score = score;
}
public void setScore(float score)
{
this.score = score;
}
public float getScore()
{
return score;
}
public static void swap(Student x, Student y)
{
Student temp = x;
x = y;
y = temp;
}
}
public class ParamTest
{
static void Main(string[] args)
{
Student a = new Student();
Student b = new Student();
Console.WriteLine("交换前:");
Console.WriteLine("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore()); Student.swap(a, b); Console.WriteLine("交换后:");
Console.WriteLine("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore());
Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 值传递和引用传递2
{
class aa {
public static void change(int[] count) {
//这里修改的是地址里面的值,所以可以修改成功
count[] = ;
} }
class Program
{
static void Main(string[] args)
{
int[] count = { , , , , };
aa.change(count);
Console.WriteLine(count[]);
Console.ReadKey(); }
}
}
4.ref函数
- 方法定义和调用方法都必须显式使用 ref 关键字
- 传递到 ref 参数的参数必须初始化,否则程序会报错
- 通过ref的这个特性,一定程度上解决了C#中的函数只能有一个返回值的问题
值传递是默认的,但是也可以迫使他变成引用传递:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 值传递和引用传递2
{
class aa {
public static void change(int[] count, ref int i)
{
count[] = ;
i = ;
} }
class Program
{
static void Main(string[] args)
{
int[] count = { , , , , };
int i = ;
aa.change(count,ref i);
Console.WriteLine(count[]);
Console.WriteLine(i);
Console.ReadKey(); }
}
}
5.out函数
- 方法定义和调用方法都必须显式使用 out关键字
- out参数的参数值初始化必须在其方法内进行,否则程序会报错
- 通过out的这个特性,一定程度上解决了C#中的函数只能有一个返回值的问题
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = ;
int b;
Fun(out a, out b);
Console.WriteLine("a:{0},b:{1}", a, b);//输出:3和1说明out参数传递进去的是a和b的引用,输出3说明a的参数值没有传入Fun方法中
Console.ReadKey();
}
static void Fun(out int a, out int b)
{
a = + ;
b = ;
}
}
}
ref和out的区别:
通过上面的解析,ref和out最主要的区别是:
ref将参数的参数值和引用都传入方法中,所以ref的参数的初始化必须在方法外部进行,也就是ref的参数必须有初始化值,否则程序会报错
out不会将参数的参数值传入方法中,只会将参数的引用传入方法中,所以参数的初始化工作必须在其对用方法中进行,否则程序会报错
ref和out的注意:
- 尽管 ref 和 out 在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法
- 如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载
5.函数的重载
方法名相同,但是参数个数和类型不同
1.方法重载:是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数
2.具体规范:
(1)方法名一定要相同。
(2)方法的参数表必须不同,包括参数的类型或个数,以此区分不同的方法体。
- a.如果参数个数不同,就不管它的参数类型了。
- b.如果参数个数相同,那么参数的类型必须不同。
(3)方法的返回类型、修饰符可以相同,也可不同。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 函数的重载
{ class Program
{
public static int AddNumber(int num1,int num2)
{
return num1 + num2; }
public static double AddNumber(int num1, int num2,int num3)
{
return num1 + num2+ num3;
} public static double AddNumber(double num1, int num2)
{
return num1 + num2;
} static void Main(string[] args)
{ Console.WriteLine(AddNumber(, ));
Console.WriteLine(AddNumber(, ));
Console.WriteLine(AddNumber(1.3f, ));
Console.ReadKey();
}
}
}
(二)属性
在C#中我们可以很自由的访问共有字段,但有时我们可能需要某字段只能读或者写,或在改变字段值得时候做一些其他事情,显然这些仅仅依靠字段是无法实现的,于是便有了属性。
c#中的属性由属性作用域中定义的get作用域(访问方法)和set作用域(访问方法)构成。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 成员函数之属性
{
class Program
{
static void Main(string[] args)
{
Test test = new Test(); Console.WriteLine(test.Num); //SavingAccount sa = new SavingAccount();
Console.WriteLine(Customers.Name);
Console.ReadKey();
} class Test
{
private int number;
//int表示该属性所封装的数据类型
//数据类型必须与相应的字段(number)相同
public int Num
{
get { return number; }
set { number = value; }
}
}
class Customers {
public int age;
//静态数据点
private static string name = "aaa";
//静态属性
public static string Name {
get { return name; }
set { name = value; }
} }
}
}
直接在代码中使用封装了数字或布尔数据的自动属性,因为隐藏的返回字段将设置一个可以直接使用的安全的默认值。但如果自动属性封装了另一个类变量,隐藏的私有引用类型的默认值将设为null。
例如下面的类spa,使用了两个自动属性
class Spa
{
//隐藏的int字段默认值为0
public int numbers{get;set;}
//隐藏的Enemy返回字段为null
public Enemy MyEnemy{get;set;}
}
(三)构造函数
- 构造函数的名字与类名相同。
- 使用 new 表达式创建类的对象或者结构(例如int)时,会调用其构造函数。并且通常初始化新对象的数据成员。
- 除非类是静态的,否则会为没有构造函数的类,自动生成一个默认构造函数,并使用默认值来初始化对象字段。
- 构造函数可以有参数,可以以多态的形式存在多个构造函数。
- 如果存在有参构造函数,那么系统就不会调用默认的。当没有任何构造函数时,才会调用默认的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 成员函数之属性之关于自动属性和默认值
{
class Customers {
public string name { get; set; }
public int age { get; set; }
public int ID { get; set; }
//构造函数:与类名相同的函数并且他的没有返回值类型
public Customers() {
//初始化
this.name = name;
this.age = age;
this.ID = ID; }
public Customers(string name, int age) {
this.name = name;
this.age = age; } }
class Program
{
static void Main(string[] args)
{
Customers customer = new Customers("dfdsa",);
Console.WriteLine(customer.name);
Console.ReadKey(); }
}
}
(1)静态构造函数
静态构造函数不使用访问修饰符或不具有参数。
在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数以初始化类。
不能直接调用静态构造函数。
用户无法控制在程序中执行静态构造函数的时间。
静态构造函数的一种典型用法是在类使用日志文件且将构造函数用于将条目写入到此文件中时使用。
静态构造函数对于创建非托管代码的包装类也非常有用,这种情况下构造函数可调用
LoadLibrary
方法。如果静态构造函数引发异常,运行时将不会再次调用该函数,并且类型在程序运行所在的应用程序域的生存期内将保持未初始化。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 构造函数之静态构造函数
{
class customers {
//静态成员变量
public static int age = ;
//构造函数
public customers() {
age = ;
}
//静态构造函数
static customers()
{
age = ;
}
} class Program
{ //第一步,程序入口Main最先执行。然后执行public static int x = 0 接着执行静态构造函数。
static void Main(string[] args)
{
Console.WriteLine("x:{0}", customers.age); //打印,age = 100
//实例化的时候访问静态变量=0; 然后访问静态构造函数=100; 最后访问构造函数=22
customers Test = new customers();
Console.WriteLine("x:{0}", customers.age); //打印age = 22
Console.ReadKey();
}
}
}
由上面的程序可以知道了静态构造函数的执行顺序:
1、静态变量 > 静态构造函数 > 静态函数
2、静态变量 > 静态构造函数 > 构造函数
菜鸟先飞C#学习总结(一)的更多相关文章
- Entity Framework菜鸟初飞
Entity Framework菜鸟初飞 http://blog.csdn.net/zezhi821/article/details/7235134
- 这是一套Java菜鸟到大牛的学习路线之高级教程,由工作了10年的资深Java架构师整理。
这是一套Java菜鸟到大牛的学习路线之高级教程,由工作了10年的资深Java架构师整理. 01-java高级架构师设计-基础深入 J2SE深入讲解 Java多 ...
- [游戏开发-学习笔记]菜鸟慢慢飞(九)- NGUI- UIWidget(官方说明翻译)
- [游戏开发-学习笔记]菜鸟慢慢飞(九)- NGUI- UIPanel(官方说明翻译)
我自己笔记是做在OneNote上,直接复制粘贴过来变成图片了,效果好像还可以. 机器翻译,我自己看了一下,改了一部分.
- [游戏开发-学习笔记]菜鸟慢慢飞(四)-Camera
游戏开发中,主相机应该是最重要的GameObject之一,毕竟游戏呈现给玩家,就是通过它. 相机的使用,在不同的游戏中,有很大的不同.这里总结一下自己学到的一些相关知识. 固定位置-游戏过程中相机的T ...
- 菜鸟快飞之JavaScript对象、原型、继承(三)
正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...
- ZENCART 菜鸟找人一起学习
ZENCART 是一个很强大的外贸CMS程序. 现在刚开始学习,虽然晚了五年…… 有兴趣的朋友加群一起学习交流吧 学习论坛: http://www.zencart-bbs.com/thread-htm ...
- HDU-ACM“菜鸟先飞”冬训系列赛——第10场
Problem A 题意 给出l(房子宽度),d(pole距离房子的垂直距离),s(绳子长度),求可覆盖的面积 分析 一共四种情况 \[1.s<=d\] \[2.s<=sqrt(d*d+l ...
- 菜鸟 ssm 框架的学习之路
跟着老师学习了两个月的java语言,现在学习到了框架的部分,一直想在博客上写点东西的,只是自己一直没有时间,其实到底也是懒,鲁迅说过:"时间就像海绵里的水,只要愿意去挤还是有的", ...
随机推荐
- Java ArrayList正确循环添加删除元素方法及分析
在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 一.foreach循环 foreach循环(Foreach loop)是计算机编程 ...
- frida的用法--Hook Java代码篇
frida是一款方便并且易用的跨平台Hook工具,使用它不仅可以Hook Java写的应用程序,而且还可以Hook原生的应用程序. 1. 准备 frida分客户端环境和服务端环境.在客户端我们可以编写 ...
- 【JVM虚拟机】(9)-- JVM是如何处理异常的
[JVM虚拟机](9)-- JVM是如何处理异常的 上篇博客我们简单说过异常信息是存放在属性表集合中的Code属性表里,那么这篇博客就单独讲Code属性表中的exception_table. 在讲之前 ...
- Docker 快速开始
1. 概念 对于开发人员和系统管理员来说,Docker是一个使用容器开发.部署和运行应用程序的平台.使用Linux容器部署应用程序称为容器化.容器并不新鲜,但是将它们用于轻松部署应用程序却很新鲜. ...
- 产品管理开发之Git工作流和分支规范推荐
前言 无论是开源项目还是内部项目,使用Git都是大势所趋,尤其是在产品管理这块,使用Git大大提高了开发效率和产品的交付频率.本篇,针对Git的工作流和分支使用,进行了一些推荐. 目录 1 产 ...
- .NET(C#、VB)APP开发——Smobiler平台控件介绍:SignatureButton控件
SignatureButton控件 一. 样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的"Smobiler Components"拖动一个Sign ...
- 六大设计原则(一)SRP单一职责原则
单一职责原则SRP(Single reponsibility principle) BO(Business Object):业务对象 Biz(Business Logic):业务逻辑 SRP最简单的例 ...
- 安卓开发笔记(十二):SQLite数据库储存(上)
SQLite数据库存储(上) 创建数据库 Android专门提供了一个 SQLiteOpenHelper帮助类对数据库进行创建和升级 SQLiteOpenHelper需要创建一个自己的帮助类去继承它并 ...
- git tag本地删除以及远程删除
假设存在tag:12345 git tag -d 12345 #删除本地记录 git push origin :refs/tags/12345 #删除远程记录 PS: 如果您觉得我的文章对您有帮助,可 ...
- ORM(三)QuerySet查询字段操作
这里的环境还是用上次的环境: Django项目:orm_practice app/models.py中有如下几个类: models.py publishing表内容如下: pid name 1 机械工 ...