博文
C# 语言规范--1.9 接口(2006-09-03 18:31:00)
摘要:一个接口定义一个协定。实现接口的类或结构必须遵守其协定。接口可以包含方法、属性、索引器和事件作为成员。
示例interface IExample
{
string this[int index] { get; set; }
event EventHandler E;
void F(int value);
string P { get; set; }
}
public delegate void EventHandler(object sender, EventArgs e);
显示了一个包含索引器、事件 E、方法 F 和属性 P 的接口。
接口可以使用多重继承。在下面的示例中,interface IControl
{
void Paint();
}
interface ITextBox: IControl
{
void SetText(string text);
}
interface IListBox: IControl
{
void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {}
接口 IComboBox 同时从 ITextBox 和 IListBox 继承。
类和结构可以实现多个接口。在下面的示例中,interface IDataBound
{
void Bind(Binder b);
}
public class EditBox: Control, IControl, IDataBound
{
public void Paint() {...}
public void Bind(Binder b) {...}
}
类 EditBox 从类 Control 派生,并且同时实现 IControl 和 IDataBound。
在前面的示例中,IControl 接口中的 Paint 方法和 IDataBound 接口中的 Bind 方法是使用 EditBox 类的公共成员实现的。C# 提供了另一种方式来实现这些方法,使得实现类避免将这些成员设置成公共的。这就是:接口成员可以用限定名来实现。例如,在 EditBox 类中将 Paint 方法命名为 ......
C# 语言规范--1.8 结构(2006-09-03 18:30:00)
摘要:类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的程序员有时可以通过聪明地使用结构来增强性能。
例如,将 Point 定义为结构而不是类在运行时可以节省很多内存空间。下面的程序创建并初始化一个 100 点的数组。对于作为类实现的 Point,出现了 101 个实例对象,因为数组需要一个,它的 100 个元素每个都需要一个。class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Test
{
static void Main() {
Point[] points = new Point[100];
for (int i = 0; i < 100; i++)
points[i] = new Point(i, i*i);
}
}
如果将 Point 改为作为结构实现,如struct Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
则只出现一个实例对象(用于数组的对象)。Point 实例在数组中内联分配。此优化可能会被误用。使用结构而不是类还会使应用程序运行得更慢或占用更多的内存,因为将结构实例作为值参数传递会导致创建结构的副本。
......
C# 语言规范--1.7 类(2006-09-03 18:30:00)
摘要:类声明定义新的引用类型。一个类可以从另一个类继承,并且可以实现多个接口。
类成员可以包括:常数、字段、方法、属性、事件、索引器、运算符、实例构造函数、析构函数、静态构造函数和嵌套类型声明。每个成员都有关联的可访问性,它控制能够访问该成员的程序文本区域。有五种可能的可访问性形式。下表概述了这些形式。
形式
直观含义
public
不限制访问。
protected
访问限于该成员所属的类或从该类派生来的类型。
internal
访问限于此程序。
protected internal
访问限于此程序或从该成员所属的类派生的类型。
private
访问限于该成员所属的类型。
示例using System;
class MyClass
{
public MyClass() {
Console.WriteLine("Instance constructor");
}
public MyClass(int value) {
MyField = value;
Console.WriteLine("Instance constructor");
}
~MyClass() {
Console.WriteLine("Destructor");
}
public const int MyConst = 12;
public int MyField = 34;
public void MyMethod(){
Console.WriteLine("MyClass.MyMethod");
}
public int MyProperty {
get {
return MyField;
}
set {
MyField = value;
}
}
public int this[int index] {
get {
return 0;
}
set {
Console.WriteLine("t......
C# 语言规范--1.6 语句(2006-09-03 18:30:00)
摘要:C# 中的大多数语句都是直接从 C 和 C++ 借用的,但有一些值得注意的添加和修改。下表列出了可用的语句类型,并提供了每种类型的示例。
语句
示例
语句列表和块语句
static void Main() {
F();
G();
{
H();
I();
}
}
标记语句和 goto 语句
static void Main(string[] args) {
if (args.Length == 0)
goto done;
Console.WriteLine(args.Length);
done:
Console.WriteLine("Done");
}
局部常数声明
static void Main() {
const float pi = 3.14f;
const int r = 123;
Console.WriteLine(pi * r * r);
}
局部变量声明
static void Main() {
int a;
int b = 2, c = 3;
a = 1;
Console.WriteLine(a + b + c);
}
表达式语句
static int F(int a, int b) {
return a + b;
}
static void Main() {
F(1, 2); // Expression statement
}
if 语句
static void Main(string[] args) {
if (args.Length == 0)
Console.WriteLine("No args");
else
Console.WriteLine("Args");
}
switch 语句
static void Main(string[] args) {
switch (args.Length) {
case 0:
......
C# 语言规范--1.5 表达式(2006-09-03 18:29:00)
摘要:C# 包含一元运算符、二元运算符和一个三元运算符。下表概述了这些运算符,并将它们按优先级以从高到低的顺序列出:
章节
类别
运算符
第 7.5 节
基本
x.y f(x) a[x] x++ x-- new
typeof checked unchecked
第 7.6 节
一元
+ - ! ~ ++x --x (T)x
第 7.7 节
乘法
* / %
第 7.7 节
加法
+ -
第 7.8 节
移位
<< >>
第 7.9 节
关系和类型检测
< > <= >= is as
第 7.9 节
相等
== !=
第 7.10 节
逻辑 AND
&
第 7.10 节
逻辑 XOR
^
第 7.10 节
逻辑 OR
|
第 7.11 节
条件 AND
&&
第 7.11 节
条件 OR
||
第 7.12 节
条件
?:
第 7.13 节
赋值
= *= /= %= += -= <<= >>= &= ^= |=
当表达式包含多个运算符时,运算符的优先级控制各运算符的计算顺序。例如,表达式 x + y * z 按 x + (y * z) 计算,因为 * 运算符具有的优先级比 + 运算符高。
当操作数出现在具有相同优先级的两个运算符之间时,运算符的顺序关联性控制运算的执行顺序:
除了赋值运算符外,所有的二元运算符都向左顺序关联,意思是从左向右执行运算。例如,x + y + z 按 (x + y) + z 计算。
赋值运算符和条件运算符 (?:) 向右顺序关联,意思是从右向左执行运算。例如,x = y = z 按 x = (y = z) 计算。
优先级和顺序关联性都可以用括号控制。例如,x + y * z 先将 y 乘以 z 然后将结果与 x 相加,而 (x + y) * z 先将 x 与 y 相加,然后再将结果乘以 z。
......
C# 语言规范--1.4 自动内存管理(2006-09-03 18:28:00)
摘要:手动内存管理要求开发人员管理内存块的分配和回收。手动内存管理可能既耗时又麻烦。在 C# 中提供了自动内存管理,使开发人员从这个繁重的任务中解脱出来。在绝大多数情况下,自动内存管理可以提高代码质量和开发人员的工作效率,并且不会对表达能力或性能造成负面影响。
示例using System;
public class Stack
{
private Node first = null;
public bool Empty {
get {
return (first == null);
}
}
public object Pop() {
if (first == null)
throw new Exception("Can't Pop from an empty Stack.");
else {
object temp = first.Value;
first = first.Next;
return temp;
}
}
public void Push(object o) {
first = new Node(o, first);
}
private class Node
{
public Node Next;
public object Value;
public Node(object value): this(value, null) {}
public Node(object value, Node next) {
Next = next;
Value = value;
}
}
}
显示了一个 Stack 类,它实际上是 Node 实例的一个链接表。Node 实例是在 Push 方法中创建的,当不再需要它们时会对其进行垃圾回收。当任何代码都不再可能访问某个 Node 实例时,该实例就成为垃圾回收的对象。例如,当从 Stack 中移除某项时,相关的 Node 实例就符合了垃圾回收条件,等......
C# 语言规范--1.3 变量和参数(2006-09-03 18:28:00)
摘要:变量表示存储位置。每个变量都属于一种类型,它确定什么样的值可以存储在该变量中。局部变量是在方法、属性或索引器中声明的变量。局部变量是通过指定类型名称和声明符(它指定变量名和可选的初始值)定义的,如:int a;
int b = 1;
但局部变量声明也可以包含多个声明符。a 和 b 的声明可以重写为:int a, b = 1;
一个变量必须先赋值,然后才能使用它的值。示例class Test
{
static void Main() {
int a;
int b = 1;
int c = a + b; // error, a not yet assigned
...
}
}
导致编译时错误,因为它试图在给变量 a 赋值之前使用它。
字段是与类或结构或与类或结构的实例关联的变量。用 static 修饰符声明的字段定义静态变量,不用此修饰符声明的字段则定义实例变量。静态字段与类型关联,而实例变量与实例关联。示例using Personnel.Data;
class Employee
{
private static DataSet ds;
public string Name;
public decimal Salary;
...
}
显示了具有一个私有静态变量和两个公共实例变量的 Employee 类。
形参声明也定义变量。有四种类型的参数:值参数、引用参数、输出参数和参数数组。
值参用于“in”参数传递。在此过程中,自变量的值被传入方法中。因为一个值参在方法中用自己的变量存储(而非原自变量),所以对此参数的修改不会影响到原自变量。值参的变量是通过复制原自变量的值来初始化的。示例using System;
class Test {
static void F(int p) {
Console.WriteLine("p = {0}", p);
p++;
}
static void Main() {
int a = 1;
Console.WriteLine("pre: a = {0}", a);
F(a);
Console.Writ......
C# 语言规范--1.2 类型(2006-09-03 18:27:00)
摘要:C# 支持两种类型:“值类型”和“引用类型”。值类型包括简单类型(如 char、int 和 float)、枚举类型和结构类型。引用类型包括类 (Class) 类型、接口类型、委托类型和数组类型。
值类型与引用类型的区别在于值类型的变量直接包含其数据,而引用类型的变量则存储对象引用。对于引用类型,两个变量可能引用同一对象,因此对一个变量的操作可能影响另一个变量所引用的对象。对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响另一个变量。
示例using System;
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
int val1 = 0;
int val2 = val1;
val2 = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
显示了这种区别。运行该程序,可见下列输出:Values: 0, 123
Refs: 123, 123
给局部变量 val1 赋值不会影响局部变量 val2,这是因为两个局部变量都是值类型(int 类型),每个局部变量都保存着各自的数据。相反,赋值 ref2.Value = 123; 则会影响到 ref2,因为 ref1 和 ref2 所引用的其实是同一个对象。
应对代码行Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
做进一步解释,因为方法 Console.WriteLine 的某些字符串格式化行为较复杂,它所需的参数数目是可变的。第一个参数是字符串,它可能包含类似 {0......
C# 语言规范--1.1 开始(2006-09-03 18:26:00)
摘要:经典性“hello, world”程序可以写为:using System;
class Hello
{
static void Main() {
Console.WriteLine("hello, world");
}
}
C# 程序的源代码通常存储在一个或多个以 .cs 为文件扩展名的文本文件(如 hello.cs)中。可以通过 Visual Studio .NET 所提供的命令行编译器,使用以下命令行指令来编译此程序:csc hello.cs
它产生一个名为 hello.exe 的应用程序。当此应用程序运行时,它产生的输出是:hello, world
仔细观察此程序可以发现:
“using System;”指令引用一个名为 System 的命名空间,它由 Microsoft .NET Framework 类库定义。此命名空间包含 Main 方法中引用的 Console 类。命名空间提供了一种分层方法来组织一个或多个程序中的各种元素。用“using”指令指定一个命名空间后,该命名空间中的所有成员均可直接被引用。所以,在“hello, world”程序中,可直接使用 Console.WriteLine(而不必使用 System.Console.WriteLine)。
Main 方法是 Hello 类的成员。它具有 static 修饰符,因此 Main 方法是相对于类 Hello 本身而不是相对于此类的实例。
应用程序的入口点(即当程序开始运行时首先被调用的方法)总是名为 Main 的静态方法。
“hello, world”输出依靠类库实现。C# 语言本身不提供类库,它使用公共的类库(Visual Basic .NET 和 Visual C++ .NET 也使用它)。
对 C 和 C++ 开发人员而言,值得注意的是一些“没有”出现在“hello, world”程序中的东西。
该程序中的 Main 方法不是全局的。C# 不支持全局级别的方法和变量;这类元素总是包含在类型声明(如类声明和结构声明)中。
该程序没有使用“::”运算符和“->”运算符。在 C# 中,“::”根本不是运算符,而“->”运算符仅在一小部分程序中使用,即那些涉及不安全代码的程序。分隔符“.”在复合名称中使用,如......
C# 程序员参考--OLE DB 教程(2006-09-03 18:26:00)
摘要:OLE DB 是用于访问数据的基于 COM 的应用程序编程接口 (API)。OLE DB 支持访问以 OLE DB 提供程序可以使用的任何格式(数据库、电子表格、文本文件等)存储的数据。每个 OLE DB 提供程序从某一特定类型的数据源(例如 SQL Server 数据库、Microsoft Access 数据库或 Microsoft Excel 电子表格)公开数据。
本教程说明如何从 C# 应用程序中使用 Microsoft Access 数据库。
教程
本教程说明如何从 C# 中使用 Microsoft Access 数据库。它显示如何创建数据集并从数据库向该数据集添加表。本示例程序中使用的 BugTypes.mdb 数据库是 Microsoft Access 2000 .MDB 文件。
示例
本程序访问 BugTypes.mdb 数据库,创建一个数据集并向其中添加表,然后显示表、列和行的数目。它还显示每行的标题。
// OleDbSample.cs
using System;
using System.Data;
using System.Data.OleDb;
using System.Xml.Serialization;
public class MainClass {
public static void Main ()
{
// Set Access connection and select strings.
// The path to BugTypes.MDB must be changed if you build
// the sample from the command line:
#i......