1.c#基础学习参考资料
在vs安装目录下\VC#\Specifications\2052有一本CSharp Language Specification的书。这是一本C#语言规范,对学习C#基础会很有帮助。
2.c#程序结构
下面举一个简单的控制台应用程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 控制台程序练习
{
class MyClass
{
//成员变量
string str;
public void f()
{
str = "你好啊";
Console.WriteLine(str);
}
}
class Program
{
static void Main(string[] args)
{
MyClass myclass = new MyClass();
myclass.f();
Console.ReadKey();
}
}
}
在程序中:
using 关键字用于在程序中包含命名空间。一个程序可以包含多个 using 语句
class 关键字用于声明一个类
namespace 是一系列的类
Main 方法,是所有 C# 程序的入口
类的成员函数是在类内声明的
3.C#数据类型
在C#中,变量分为:
值类型
引用类型
指针类型
值类型(Value types):
值类型是从类System.ValueType中派生的。
类型 | 描述 | 默认值 |
bool | 布尔值 | False |
byte | 8位无符号整数 | 0 |
char | 16位Unicode字符 | '\0' |
decimal | 128位精确的十进值,28-29有效位 | 0.0M |
double | 64位双精度浮点型 | 0.0D |
float | 32位单精度浮点型 | 0.0F |
int | 32位有符号整数类型 | 0 |
long | 64位有符号整数类型 | 0L |
sbyte | 8位有符号整数类型 | 0 |
short | 16位有符号整数类型 | 0 |
uint | 32位无符号整数类型 | 0 |
ulong | 64位无符号整数类型 | 0 |
ushort | 16位无符号整数类型 | 0 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 控制台程序练习
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Size of int:{0}",sizeof(int));
Console.ReadLine();
}
}
}
引用类型(Reference types):
引用类型主要包括:对象类型,动态类型,字符串类型等
对象(Object)类型
对象类型是C#中所有数据类型的终极基类。
Object 是 System.Object 类的别名。所以对象(Object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。
当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
object obj;
obj = 100; // 这是装箱
动态类型(Dynamic)类型
您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
声明动态类型的语法:
dynamic <variable_name> = value;
例如:
dynamic d = 20;
动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
字符串(String)类型字符串类型是System.String类的别名。字符串(String)类型的值可以通过两种形式进行分配:引号和 @引号。
C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待
指针类型(Pointer types)
指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。
声明指针类型的语法:
type* identifier;
例如:
char* cptr; int* iptr;4.定义常量
常量是使用 const 关键字来定义的 。定义一个常量的语法如下:
const <data_type> <constant_name> = value;
下面的代码演示了如何在程序中定义和使用常量:
using System; namespace DeclaringConstants { class Program { static void Main(string[] args) { const double pi = 3.14159; // 常量声明 double r; Console.WriteLine("Enter Radius: "); r = Convert.ToDouble(Console.ReadLine()); double areaCircle = pi * r * r; Console.WriteLine("Radius: {0}, Area: {1}", r, areaCircle); Console.ReadLine(); } } }5.C#封装
封装被定义为"把一个或多个项目封装在一个物理的或者逻辑的包中"。
public
同一程序集中或引用了该程序集的程序
private
只有同一类中。
protected
只有同一类或其子类。
internal
同一程序集中。
protected internal
由其声明的程序集或另一个程序集派生的类中任何代码都可访问的类型或成员。
6.C#方法传值
第一种:按值传递参数(默认)
第二种:按引用传递参数(使用ref关键字)
按引用传递例子:
using System; namespace CalculatorApplication { class NumberManipulator { public void swap(ref int x, ref int y) { int temp; temp = x; /* 保存 x 的值 */ x = y; /* 把 y 赋值给 x */ y = temp; /* 把 temp 赋值给 y */ } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a = 100; int b = 200; Console.WriteLine("在交换之前,a 的值: {0}", a); Console.WriteLine("在交换之前,b 的值: {0}", b); /* 调用函数来交换值 */ n.swap(ref a, ref b); Console.WriteLine("在交换之后,a 的值: {0}", a); Console.WriteLine("在交换之后,b 的值: {0}", b); Console.ReadLine(); } } }第三按输出传递参数
return 语句可用于只从函数中返回一个值。但是,可以使用 输出参数 来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
下面的实例演示了这点:
using System; namespace CalculatorApplication { class NumberManipulator { public void getValue(out int x ) { int temp = 5; x = temp; } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a = 100; Console.WriteLine("在方法调用之前,a 的值: {0}", a); /* 调用函数来获取值 */ n.getValue(out a); Console.WriteLine("在方法调用之后,a 的值: {0}", a); Console.ReadLine(); } } }7.C#可空类型(Nullable)
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。
声明一个 nullable 类型(可空类型)的语法如下:
< data_type> ? <variable_name> = null;
下面的实例演示了可空数据类型的用法:
using System; namespace CalculatorApplication { class NullablesAtShow { static void Main(string[] args) { int? num1 = null; int? num2 = 45; double? num3 = new double?(); double? num4 = 3.14157; bool? boolval = new bool?(); // 显示值 Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}", num1, num2, num3, num4); Console.WriteLine("一个可空的布尔值: {0}", boolval); Console.ReadLine(); } } }
当上面的代码被编译和执行时,它会产生下列结果:
显示可空类型的值: , 45, , 3.14157 一个可空的布尔值:Null合并运算符(??)
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。下面的实例演示了这点:
using System; namespace CalculatorApplication { class NullablesAtShow { static void Main(string[] args) { double? num1 = null; double? num2 = 3.14157; double num3; num3 = num1 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); Console.ReadLine(); } } }
当上面的代码被编译和执行时,它会产生下列结果:
num3 的值: 5.34 num3 的值: 3.141578.C#数组
声明数组:
datatype[] arrayName;初始化数组:
double[] balance = new double[10];赋值数组(主要使用的分为两种)
第一种:
double[] balance = new double[10]; balance[0] = 4500.0;第二种:
double[] balance = { 2340.0, 4523.69, 3421.0};9.C#结构
在C#中,结构是值类型数据结构。
定义结构:
struct Books { public string title; public string author; public string subject; public int book_id; };C#结构的特点
您已经用了一个简单的名为 Books 的结构。在 C# 中的结构与传统的 C 或 C++ 中的结构不同。C# 中的结构有以下特点:
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。
- 结构不能作为其他结构或类的基础结构。
- 结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
类和结构有以下几个基本的不同点:
- 类是引用类型,结构是值类型。
- 结构不支持继承。
- 结构不能声明默认的构造函数。
10.C#枚举(Enum)
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。
C# 枚举是值数据类型。换句话说,枚举包含自己的值,且不能继承或传递继承。
enum <enum_name> { enumeration list };
其中,
- enum_name 指定枚举的类型名称。
- enumeration list 是一个用逗号分隔的标识符列表。
枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是 0.例如:
enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };11.C#继承
C#中用":"表示继承,继承多个时类放前边,接口放后边中间用","隔开。
C#不支持多重继承。但是可以通过使用接口来实现多继承。
using System; namespace InheritanceApplication { class Shape { public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } protected int width; protected int height; } // 基类 PaintCost public interface PaintCost { int getCost(int area); } // 派生类 class Rectangle : Shape, PaintCost { public int getArea() { return (width * height); } public int getCost(int area) { return area * 70; } } class RectangleTester { static void Main(string[] args) { Rectangle Rect = new Rectangle(); int area; Rect.setWidth(5); Rect.setHeight(7); area = Rect.getArea(); // 打印对象的面积 Console.WriteLine("总面积: {0}", Rect.getArea()); Console.WriteLine("油漆总成本: ${0}" , Rect.getCost(area)); Console.ReadKey(); } } }
当上面的代码被编译和执行时,它会产生下列结果:
总面积: 35 油漆总成本: $245012.C#运算符重载
重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样,重载运算符有返回类型和参数列表。
例如,请看下面的函数:
public static Box operator+ (Box b, Box c) { Box box = new Box(); box.length = b.length + c.length; box.breadth = b.breadth + c.breadth; box.height = b.height + c.height; return box; }
上面的函数为用户自定义的类 Box 实现了加法运算符(+)。它把两个 Box 对象的属性相加,并返回相加后的 Box 对象。
下表描述了 C# 中运算符重载的能力:
运算符 | 描述 |
---|---|
+, -, !, ~, ++, -- | 这些一元运算符只有一个操作数,且可以被重载。 |
+, -, *, /, % | 这些二元运算符带有两个操作数,且可以被重载。 |
==, !=, <, >, <=, >= | 这些比较运算符可以被重载。 |
&&, || | 这些条件逻辑运算符不能被直接重载。 |
+=, -=, *=, /=, %= | 这些赋值运算符不能被重载。 |
=, ., ?:, ->, new, is, sizeof, typeof | 这些运算符不能被重载。 |