目录

1. 特殊的数据成员........................................................................... 1

2. 数组(array)............................................................................. 1

3. 命名空间(namespace)................................................................. 2

4. 方法的参数传递........................................................................... 2

5. 构造器(constructor)................................................................. 3

6. 析构(Destructor)...................................................................... 4

7. 访问控制修饰符........................................................................... 5

8. 类型转换....................................................................................... 6

9. 属性(Property).......................................................................... 7

10. 索引器(indexer)....................................................................... 8

11. 委托(delegate)...................................................................... 10

12. 事件(event)............................................................................. 11

13. 虚方法(virtual)..................................................................... 13

14. 抽象类(abstract)................................................................... 14

15. 接口(interface).................................................................... 14

16. 排序(IComparable与IComparer)......................................... 17

17. 扩展方法................................................................................... 19

18. 密封类和密封方法(sealed).................................................... 20

19. yield return语句动态的返回集合....................................... 20

20. 多线程的应用........................................................................... 20

 

1.特殊的数据成员

(1)      常量const

定义方式:const int g = 10;

注意:常量的值必须在声明时初始化,常量的值不可变化,常量本身就是静态的不能使用static修饰。

(2)      只读字段readonly

定义方式:private readonly int t;

注意:只读字段必须在声明时或类构造方法中初始化,只读字段的值不可变化,只读字段不一定是静态的可以使用static修饰。

2.数组(array)

(1)      一维数组

定义方式:

int[] array=new int[num];

int[] array = { 1, 2, 3, 4, 5, 6 };

int[] array = new int[] { 1, 2, 3, 4, 5, 6 };

(2)      多维数组

定义方式:

int[,] array=new int[low,row];

int[,] array={{1,2},{5,6}};(一维的维度要一致)

int[,] array = new int[2,2]{{1,2},{5,6}};

(3)      不规则数组(数组的数组)

int[][] array=new int[3][];

array[0] = new int[] { 1, 2, 3, 4 };

array[1] = new int[] { 1, 2, 3};

array[2] = new int[] { 1, 2};

int[][,] array=new int[3][,];

(4)      数组遍历

遍历规则数组:

for (int i = 0; i < array.GetLength(0); i++)

{

for (int j = 0; j < array.GetLength(1); j++)

{

Console.Write(array[i,j] + " ");

}

Console.WriteLine();

}

遍历不规则数组:

for (int i = 0; i < array.Length; i++)

{

for (int j = 0; j < array[i].Length; j++)

{

Console.Write(array[i][j] + " ");

}

Console.WriteLine();

}

3.命名空间(namespace)

C#命名空间与Java的包一样,不同的程序文件里的类可以在同一命名空间里。命名空间可以嵌套。

4.方法的参数传递

(1)      值传递

代码形式:方法名称 (参数类型 参数名称)

说明:此方式并无特别之处。

(2)      引用参数(ref)

代码形式:方法名称 (ref 参数类型 参数名称)

说明:传递参数的引用可以改变原参数(实参),但是需要初始化实参。下面代码输出1。

class Program

{

static void add(ref int i)

{

i++;

}

static void Main(string[] args)

{

int i = 0;//必须先初始化

add(ref i);//调用时必须加ref

Console.WriteLine(i);

}

}

(3)      输出参数(out)

代码形式:方法名称 (out 参数类型 参数名称)

说明:传递参数的引用可以改变原参数(实参),但是在使用前需要初始化参数。下面代码输出100。

class Program

{

static void add(out int i)

{

i = 0;//必须在使用前初始化

i=100;

}

static void Main(string[] args)

{

int i;

add(out i);//调用时必须加out

Console.WriteLine(i);

}

}

(4)      传递可变数量的参数(params)

代码形式:方法名称 (params参数类型 参数名称)

说明:传递的参数数量不定,可以变化。下面的程序输出1 2 3。

class Program

{

static void Print(params int[] array)

{

foreach (int i in array)

{

Console.Write(i + " ");

}

}

static void Main(string[] args)

{

Print(1,2);

Print(3);

}

}

5.构造器(constructor)

(1)      创建对象的过程—无参构造器

class A

{

public A(int i){ }

}

class B : A

{  }

class Program

{

static void Main(string[] args)

{

new B();//无法创建对象

}

}

以上的程序无法创建B类对象,因为创建B类对象调用B类的默认构造器时会默认的调用其基类A的无参构造器,而A类却没有无参构造器,所以不能创建B类对象。

(2)      使用base调用基类构造器

class A

{

public A(int i) { }

}

class B : A

{

public B() : base(5) { }//调用A类的有参构造

}

class Program

{

static void Main(string[] args)

{

new B();//可以创建对象

}

}

(3)      静态构造器(Java中的静态初始化器)

静态构造器最多执行一次,执行在静态成员初始化完毕之后。下面程序输出20。

class Program

{

static void Main(string[] args)

{

Console.WriteLine(A.i);

}

}

class A

{

public static int i = 10;

static A()

{

i = 20;

}

}

6.析构(Destructor)

(1)      析构函数(Finalize操作)

下面程序运行结果:构造A构造A析构A析构A。

class Program

{

static void Main(string[] args)

{

new A();

new A();

}

}

class A

{

public A()

{

Console.Write("构造A");

}

~A()//析构

{

Console.Write("析构A");

}

}

(2)      在一般情况下不要实现析构函数,这会影响垃圾回收的性能。

(3)      显示调用垃圾回收:GC.Collect()会建议程序调用垃圾回收,微软强烈建议不要这样做!

(4)      释放模式,IDisposable接口

class A:IDisposable

{

private bool disposed = false;//标志是否已释放资源

protected virtual void Dispose(bool disposing)

{

if (!this.disposed)

{

if (disposing)

{

Console.WriteLine("调用所引用的类的Dispose()方法!");

}

Console.WriteLine("调用类本身的非托管资源!");

disposed = true;

}

}

public void Dispose()

{

Dispose(true);//调用手动释放资源

GC.SuppressFinalize(this);//阻止调用终结器

}

~A()

{

Dispose(false);

}

}

对于下面主方法,执行结果:调用类本身的非托管资源!

class Program

{

static void Main(string[] args)

{

A a = new A();

}

}

对于下面主方法,执行结果:

调用所引用的类的Dispose()方法!

调用类本身的非托管资源!

class Program

{

static void Main(string[] args)

{

A a = new A();

a.Dispose();

a.Dispose();

}

}

(5)      对于继承了IDisposable接口的类,使用using简化try{}finally{}

对于下面的两个主方法,执行结果都是:

使用a对象

调用所引用的类的Dispose()方法!

调用类本身的非托管资源!

class Program

{

static void Main(string[] args)

{

A a = new A();

try

{ Console.WriteLine("使用a对象"); }

finally

{ a.Dispose(); }

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

using (a)//使用using

{

Console.WriteLine("使用a对象");

}

}

}

7.访问控制修饰符

(1)      修饰符的访问范围(空白表示不能访问)

访问控制修饰符

类内部

子类

程序集内

程序集外

default

可以访问

public

可以访问

可以访问

可以访问

可以访问

private

可以访问

internal

可以访问

可以访问

可以访问

protected

可以访问

可以访问

protected internal

可以访问

可以访问

可以访问

子类可以访问

(2)      总结:在C#1.0中,不声明任何修饰符,默认是私有的方法,也就是说default与private一样。当父类和子类在同一程序集时,子类可以访问父类的internal成员,当父类和子类不在同一程序集时,子类不可以访问父类的internal成员,但可以访问父类的protected interal成员。

8.类型转换

(1)      使用checked与unchecked检测抓换的异常(如:溢出)

下面程序会出现溢出异常,而中断执行。

class Program

{

static void Main(string[] args)

{

long a = 1000000000000;

int b;

b = checked((int)a);//使用checked检测是否溢出

}

}

下面程序会忽略溢出异常。

class Program

{

static void Main(string[] args)

{

long a = 1000000000000;

int b;

b = unchecked((int)a);//使用unchecked忽略溢出异常,默认也是忽略溢出异常

}

}

(2)      使用is判断类型

下面程序的执行结果:True False True True

class A

{ }

class B:A

{ }

class Program

{

static void Main(string[] args)

{

A a = new A();

B b = new B();

Console.WriteLine(a is A);

Console.WriteLine(a is B);

Console.WriteLine(b is A);

Console.WriteLine(b is B);

}

}

(3)      使用as操作符(使用as比is效率高)

class A

{ }

class B:A

{ }

class Program

{

static void Main(string[] args)

{

A a = new A();

B b = a as B;//转换失败返回null

if (a != null)

{

Console.WriteLine("转换成功");

}

}

}

9.属性(Property)

(1)      使用属性访问私有成员

class A

{

private string m_name;

public string Name

{

get

{ return m_name; }

set

{

if (value!=null)//赋值前的处理

m_name = value;

}

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a.Name = "lizhiwei";

Console.WriteLine(a.Name);

}

}

(2)      访问静态成员的属性

class A

{

private static int m_num=0;

public A()

{

m_num++;

}

public static int Num

{

get

{ return m_num; }

}

}

class Program

{

static void Main(string[] args)

{

new A();

Console.WriteLine(A.Num);

new A();

Console.WriteLine(A.Num);

}

}

10.索引器(indexer)

(1)      使用索引器

下面程序运行结果:1  2

class A

{

private int[] array=new int[20];

public int this[int index]//索引器

{

get

{ return array[index]; }

set

{ array[index] = value; }

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a[0] = 1;//访问索引器set

a[19] = 2;//访问索引器set

Console.WriteLine(a[0] + " " + a[19]);//访问索引器get

}

}

(2)      索引器的重载

下面的程序运行结果:lizhiwei li

class A

{

private Hashtable m_map = new Hashtable();

public string this[string key]//索引器

{

get

{ return m_map[key].ToString(); }

set

{ m_map[key] = value; }

}

public string this[int key]//重载索引器

{

get

{ return m_map[key].ToString(); }

set

{ m_map[key] = value; }

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a["001"] = "lizhiwei";

a[2] = "li";

Console.WriteLine(a["001"]+" "+a[2]);

}

}

(3)      多参数的索引器

下面程序运行结果:20 10

class A

{

private string m_name;

private int m_age;

private string m_sex;

public string Name

{

get

{ return m_name; }

set

{ m_name = value; }

}

public int Age

{

get

{ return m_age; }

set

{ m_age = value; }

}

public string Sex

{

get

{ return m_sex; }

set

{ m_sex=value; }

}

}

class B

{

private ArrayList m_list = new ArrayList();

public int this[string name, string sex]

{

get

{

foreach (A a in m_list)

{

if (a.Name.Equals(name) && a.Sex.Equals(sex))

{

return a.Age;

}

}

return -1;

}

set

{

A a=new A();

a.Name=name;

a.Sex=sex;

a.Age=value;//value的类型与返回值类型一致(这里是int)

m_list.Add(a);

}

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

b["李志伟", "男"] = 20;

b["张三", "男"] = 10;

Console.Write(b["李志伟", "男"]+" "+b["张三", "男"]);

}

}

(4)      注意:索引器不能是静态(static)的!

11.委托(delegate)

(1)      委托的使用(类似指向函数的指针)

下面程序运行结果:李志伟

delegate void PrintDelegate(string s);//申明委托

class A

{

public void Print(string s)//与委托的返回值、参数相同的函数

{

Console.WriteLine(s);

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

PrintDelegate s=new PrintDelegate(a.Print);//新建委托链

s("李志伟");//执行委托连

}

}

(2)      委托链的使用

下面程序的运行结果:

a1李志伟 a2李志伟 a2李志伟

a1李志伟 a2李志伟

delegate void PrintDelegate(string s);//申明委托

class A

{

private string name;

public A(string name)

{

this.name = name;

}

public void Print(string s)//与委托的返回值、参数相同的函数

{

Console.Write(name+s+" ");

}

}

class Program

{

static void Main(string[] args)

{

A a1 = new A("a1");

A a2 = new A("a2");

PrintDelegate s=new PrintDelegate(a1.Print);//新建委托链

s += new PrintDelegate(a2.Print);//增加委托链

s += new PrintDelegate(a2.Print);//增加委托链

s("李志伟");//执行委托链

Console.WriteLine();

s -= new PrintDelegate(a2.Print);//减少委托链

s("李志伟");//执行委托链

}

}

(3)      直接使用委托调用匿名方法

delegate void PrintDelegate(string s);//申明委托

class Program

{

static void Main(string[] args)

{

PrintDelegate s=null;

s += delegate(string temp) { Console.WriteLine(temp); };//委托指向匿名方法

s("李志伟");//执行委托连

}

}

(4)      使用Action<T>与Func<in T,out TResult>省略委托的定义

当委托没有返回值时使用Action<T>,有返回值时使用Func<in T,out TResult>。例如:

class Program

{

private void Hello(string name)//无返回值

{

Console.WriteLine("你好,"+name+"!");

}

private string GETAge(int age)//有返回值

{

Console.WriteLine("我的年龄:" + age + "!");

return "我的年龄:" + age + "!";

}

static void Main(string[] args)

{

Program p = new Program();

Action<string> action = p.Hello;

//Action<string> hello = new Action<string>(p.Hello);

action("李志伟");//执行委托

Func<int, string> fun = p.GETAge;

Console.WriteLine(fun(20));//执行委托

}

}

(5)      Lambda表达式,方便的使用匿名方法

class Program

{

static void Main(string[] args)

{

//标准的Lambda格式

Func<int, int, string> sum = (int a, int b) => { return "和是:" + (a + b); };

Console.WriteLine(sum(5, 6));//和是:11

//简写格式

Action<string> action = param => Console.WriteLine(param);//委托匿名方法

action("调用委托");

Func<int, Double> func = param => param * param;//有返回值的匿名方法

Console.WriteLine(func(5));//25,调用委托返回25

}

}

12.事件(event)

(1)      实现事件委托的原理

下面的程序运行的结果:

事件被触发,执行事件委托链!

执行触发事件执行的方法!

执行触发事件执行的方法!

class A

{

public delegate void Publish();//事件方法的委托

public event Publish OnPublish;//事件委托链

public void OnEvent()//触发事件,执行事件委托链

{

if (OnPublish != null)//事件委托链不为null

{

Console.WriteLine("事件被触发,执行事件委托链!");

OnPublish();//执行事件委托链

}

}

public void Event()//触发事件执行的方法

{

Console.WriteLine("执行触发事件执行的方法!");

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a.OnPublish += new A.Publish(a.Event);//订阅(注册)事件,本质是增加委托链

a.OnPublish += new A.Publish(a.Event);//订阅(注册)事件,本质是增加委托链

a.OnEvent();//触发事件,执行事件委托链

}

}

(2)      .NET Framework事件设计准则

申明delegate时,使用void类型当做返回值,EventName事件的事件委托时EventNameEventHandler,事件接受两个传入参数,一律命名sender与e。定义一个提供事件数据的类,对类EventNameEventArgs进行命名,从System.EventArgs派生该类,然后添加所有事件特定的成员。

//包含事件数据的类,命名方式:EventNameEventArgs

class AEventArgs : EventArgs

{

private readonly string name;//只读属性

public AEventArgs(string name)

{

this.name = name;

}

public string Name

{

get

{ return name; }

}

}

//引发事件的类

class B

{

//事件方法的委托,命名方式EventNameEventHandler

public delegate void PublishEventHandler(object sender,AEventArgs e);

//事件委托链

public event PublishEventHandler Publish;

//引发执行事件委托链的方法,命名方式:OnEventName

protected virtual void OnEvent(AEventArgs e)

{

PublishEventHandler handler = Publish;

if (handler != null)

{

handler(this,e);

}

}

//触发事件的方法

public void TriggerEvent(string name)

{

Console.WriteLine("事件被触发!!!");

//调用引发执行事件委托链的方法

OnEvent(new AEventArgs(name));

}

//事件处理的方法

public void HandlingEvents(object sender, AEventArgs e)

{

Console.WriteLine(e.Name+" 处理事件!!!");

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

//订阅(注册)事件,本质是增加委托链

b.Publish += new B.PublishEventHandler(b.HandlingEvents);

b.TriggerEvent("李志伟");

}

}

上面的程序使用了.NET Framework事件设计准则,运行结果:

事件被触发!!!

李志伟 处理事件!!!

13.虚方法(virtual)

(1)      使用new隐藏基类方法

下面的程序运行结果:A.print  B.print

class A

{

public void print()

{

Console.WriteLine("A.print");

}

}

class B : A

{

public new void print()//使用new显示的隐藏基类相同方法

{

Console.WriteLine("B.print");

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

A a = b;

a.print();//A.print

b.print();//B.print

}

}

(2)      使用virtual与override覆盖基类方法(实现了多态)

下面程序运行结果:B.print  B.print

class A

{

public virtual void print()//使用virtual申明虚方法

{

Console.WriteLine("A.print");

}

}

class B : A

{

public override void print()//使用override覆盖基类虚方法

{

Console.WriteLine("B.print");

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

A a = b;

a.print();//B.print

b.print();//B.print

}

}

14.抽象类(abstract)

(1)抽象类的使用

abstract class A

{

protected string m_name;

public abstract void print();//抽象方法

public abstract string Name//抽象属性,也可使用抽象索引器

{

set;

get;

}

}

class B : A

{

public override void print()//必须使用override或new,否则报错

{

Console.WriteLine(base.m_name);

}

public override string Name//必须使用override或new,否则报错

{

set{ base.m_name=value;}

get{ return base.m_name;}

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

b.Name = "李志伟";

b.print();

}

}

(2)不能有静态(static)的抽象方法,也不能有静态的抽象属性!

15.接口(interface)

(1)接口的使用

interface IA

{

void print();//抽象方法,不能使用public等修饰符

string Name//抽象属性,也可使用抽象索引器

{

set;

get;

}

}

class B : IA

{

private string m_name;

public void print()//不能使用override或new

{

Console.WriteLine(m_name);

}

public string Name//不能使用override或new

{

set{ m_name=value;}

get{ return m_name;}

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

b.Name = "李志伟";

b.print();

}

}

(2)接口里不能包含成员变量、构造器、析构器,接口的抽象方法不能使用修饰符(如:abstract、public等),因为抽象方法必须是public abstract。

(3)使用完全限定接口成员名(显示接口成员实现)

interface IA

{

void print();

}

interface IB

{

void print();

}

class A:IA,IB

{

void IA.print()//显示接口成员实现,不能使用public等关键字,只能是private

{

Console.WriteLine("IA.print");

}

void IB.print()//显示接口成员实现,不能使用public等关键字,只能是private

{

Console.WriteLine("IB.print");

}

public void print()

{

Console.WriteLine("A.print");

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

((IA)a).print();//使用IA接口访问,IA的print()

((IB)a).print();//使用IB接口访问,IB的print()

a.print();//只能访问自己的print()

}

}

上面程序运行结果:IA.print  IB.print  A.print

(4)接口的复杂使用(复杂的多重继承)

(a)直观隐藏规则

interface IA

{

void F();

}

interface IB : IA

{

new void F();//隐藏了IA的F()

}

interface IC : IA

{

void G();

}

interface IBC : IB, IC

{

}

class Test : IBC

{

public void F()

{

Console.WriteLine("IB.F");//由于IB隐藏了IA的F(),所以这里实现的是IB的F()

}

public void G()

{

Console.WriteLine("IC.G");

}

}

class Program

{

static void Main(string[] args)

{

Test t = new Test();

t.F();

((IA)t).F();

((IB)t).F();

((IC)t).F();//值得注意,由于IB隐藏了IA的F(),所以这里调用的是IB的F()

((IBC)t).F();

}

}

上面程序运行结果:IB.F IB.F IB.F IB.F IB.F

(b)接口的重新实现

interface IA

{

void print();

}

class A : IA

{

void IA.print()//接口的继承

{

Console.WriteLine("A.print");

}

}

class B:A,IA

{

public void print()//接口的重新实现,将会覆盖接口的继承,所以A的print()被完全覆盖

{

Console.WriteLine("B.print");

}

}

class Program

{

static void Main(string[] args)

{

B b = new B();

((IA)b).print();

}

}

上面程序运行结果:B.print

16.排序(IComparable与IComparer)

(1)基本数据类型的排序

class Program

{

static void Main(string[] args)

{

int[] array = {2,3,6,9,8,4,7,5,0};

Array.Sort(array);//排序方法

foreach(int i in array)

{

Console.Write(i+" ");

}

}

}

上面的程序运行结果:0 2 3 4 5 6 7 8 9

(2)自定义的类型的排序(实现IComparable接口)

class A:IComparable

{

private string name;

private int age;

public A(string name, int age)

{

this.name = name;

this.age = age;

}

public int CompareTo(object obj)//实现比较的方法

{

A temp;

if(obj is A)

{

temp=obj as A;

}

else

{

throw new ArgumentException("类型不一致!");

}

return this.name.CompareTo(temp.name);//根据姓名排序

}

public override string ToString()

{

return "[" + name + " " + age + "]";

}

}

class Program

{

static void Main(string[] args)

{

A[] array =new A[3];

array[0] = new A("李志伟",20);

array[1] = new A("张三", 19);

array[2] = new A("李四", 17);

Array.Sort(array);//排序方法,对自定义类型进行排序

foreach(A i in array)

{

Console.Write(i+" ");

}

}

}

(3)为自定义的类定义排序类(IComparer接口)

class A

{

private string name;

private int age;

public A(string name, int age)

{

this.name = name;

this.age = age;

}

public string Name

{

get { return name; }

}

public int Age

{

get { return age; }

}

public override string ToString()

{

return "[" + name + " " + age + "]";

}

}

class B : IComparer//专为类A设计的排序类

{

private static B b;

private B()

{

}

public static B GetB()

{

if (b == null)

{

b = new B();

}

return b;

}

public int Compare(Object x, Object y)//实现排序方法

{

A xa, ya;

if ((x is A) && (y is A))

{

xa = x as A;

ya = y as A;

}

else

{

throw new ArgumentException("类型不一致!");

}

return xa.Name.CompareTo(ya.Name);//根据姓名排序

}

}

class Program

{

static void Main(string[] args)

{

A[] array =new A[3];

array[0] = new A("李志伟",20);

array[1] = new A("张三", 19);

array[2] = new A("李四", 17);

Array.Sort(array,B.GetB());//排序方法

foreach(A i in array)

{

Console.Write(i+" ");

}

}

}

17.扩展方法

(1)说明:

通过扩展方法,我们可以对已有类型做自己想做的相关扩展而不需要已有类型的源代码。扩展方法是通过额外的静态方法扩展现有的类型。也可以对String,Int,DataTable等类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码。

(2)例子:

public static class MyExtensions//静态的扩展类

{

public static int StringExtensions(this String str)//为String类增加一个方法

{

Console.WriteLine(str);

return str.Length;

}

public static String StringJoin(this String str1,String str2)//为String类增加一个方法

{

Console.WriteLine(str1+str2);

return str1 + str2;

}

}

class Program

{

static void Main(string[] args)

{

String s = "12345678";

s.StringExtensions();//测试自定义的扩展方法

s.StringJoin("000000000000000");//测试自定义的扩展方法

}

}

(3)注意:

如果扩展方法包含参数,就可以在要扩展的类型(即第一个参数)以后顺序的添加扩展方法对应的参数既可,在调用的时候填写相应参数,不过请记住,第一个参数是要扩展的类型,其前面要加this关键字,在填写实参的时候并没有这个参数。

18.密封类和密封方法(sealed)

(1)Sealed修饰类不能被继承,sealed修饰方法不能被重写,类似Java的Final关键字。

19.yield return语句动态的返回集合

class Program

{

static IEnumerable<string> GetEnumerator(int a, int b)

{

long d = 1;

for (int i = 1; i <= b; i++)

{

d = a * d;

yield return a + "的" + i + "次方是:" + d;//多次被执行

}

}

static void Main(string[] args)

{

foreach (string s in GetEnumerator(2,20))//遍历返回的集合

{

Console.WriteLine(s);

}

}

}

20.多线程的应用

(1)多线程的基本使用

不需要传递参数,也不需要返回参数:

class Program

{

static void Main(string[] args)

{

for (int i = 0; i < 30; i++)

{

ThreadStart threadStart = new ThreadStart(Calculate);

Thread thread = new Thread(threadStart);

thread.Start();

}

Thread.Sleep(2000);

Console.Read();

}

public static void Calculate()

{

DateTime time = DateTime.Now;//得到当前时间

Random ra = new Random();//随机数对象

Thread.Sleep(ra.Next(10,100));//随机休眠一段时间

Console.WriteLine(time.Minute + ":" + time.Millisecond);

}

}

ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值。

需要传递单个参数:

class Program

{

static void Main(string[] args)

{

for (int i = 0; i < 30; i++)

{

ParameterizedThreadStart tStart = new ParameterizedThreadStart(Calculate);

Thread thread = new Thread(tStart);

thread.Start(i*10+10);//传递参数

}

Thread.Sleep(2000);

Console.Read();

}

public static void Calculate(object arg)

{

Random ra = new Random();//随机数对象

Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间

Console.WriteLine(arg);

}

}

ParameterThreadStart委托定义为void ParameterizedThreadStart(object state),有一个参数但是没有返回值。

使用专门的线程类:

class Program

{

static void Main(string[] args)

{

MyThread mt = new MyThread(100);

ThreadStart threadStart = new ThreadStart(mt.Calculate);

Thread thread = new Thread(threadStart);

thread.Start();

//等待线程结束

while (thread.ThreadState != ThreadState.Stopped)

{

Thread.Sleep(10);

}

Console.WriteLine(mt.Result);//打印返回值

Console.Read();

}

}

public class MyThread//线程类

{

public int Parame { set; get; }//参数

public int Result { set; get; }//返回值

//构造函数

public MyThread(int parame)

{

this.Parame = parame;

}

//线程执行方法

public void Calculate()

{

Random ra = new Random();//随机数对象

Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间

Console.WriteLine(this.Parame);

this.Result = this.Parame * ra.Next(10, 100);

}

}

使用线程类可以有多个参数与多个返回值,十分灵活!

使用匿名方法:

class Program

{

static void Main(string[] args)

{

int Parame = 100;//当做参数

int Result = 0;//当做返回值

//匿名方法

ThreadStart threadStart = new ThreadStart(delegate()

{

Random ra = new Random();//随机数对象

Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间

Console.WriteLine(Parame);//输出参数

Result = Parame * ra.Next(10, 100);//计算返回值

});

Thread thread = new Thread(threadStart);

thread.Start();//多线程启动匿名方法

//等待线程结束

while (thread.ThreadState != ThreadState.Stopped)

{

Thread.Sleep(10);

}

Console.WriteLine(Result);//打印返回值

Console.Read();

}

}

使用匿名方法启动线程可以有多个参数和返回值,而且使用非常方便!

(2)如何判断线程已经运行完成

使用System.Threading.ThreadState枚举判断线程状态,与Thread.ThreadState 属性配合使用。

C#核心语法的更多相关文章

  1. 第二章 JavaScript核心语法

    第二章   avaScript核心语法 一.变量的声明和赋值 JavaScript是一种弱类型语言,没有明确的数据类型,也就是在声明变量时不需要指定数据类型,变量的类型由赋给变量的值决定. 在Java ...

  2. css基本概念与css核心语法介绍

    css基本概念 css是什么?不需要了解太多文字类介绍,记住css是层叠样式表,HTML是页面结构,css负责页面样式,javascrt负责静态页面的交互.CSS 能够对网页中元素位置的排版进行像素级 ...

  3. [php入门] 2、基础核心语法大纲

    1 前言 最近在学PHP,上节主要总结了PHP开发环境搭建<[php入门] 1.从安装开发环境环境到(庄B)做个炫酷的登陆应用>.本节主要总结PHP的核心基础语法,基本以粗轮廓写,可以算作 ...

  4. ART-TEMPLATE的核心语法

    模板引擎语法 核心方法 // 基于模板名渲染模板 template(filename, data); // 将模板源代码编译成函数 template.compile(source, options); ...

  5. 黑马程序员——OC语言 核心语法(2)

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)id 1)简介:万能指针,能指向任何OC对象,相当于NSObject ...

  6. 黑马程序员——OC语言 核心语法(1)

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)点语法 点语法其实本质上还是方法调用 当使用点语法时,编译器会自动展 ...

  7. OC语言-04-OC语言-核心语法

    一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...

  8. OC - 4.OC核心语法

    一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...

  9. C#核心语法讲解-泛型(详细讲解泛型方法、泛型类、泛型接口、泛型约束,了解协变逆变)

    泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...

  10. Java基础学习笔记二十三 Java核心语法之反射

    类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任 ...

随机推荐

  1. VC++ 网络编程总结(一)

    1.套接字编程原理         一个完整的网间通信进程需要由两个进程组成,并且只能用同一种高层协议.也就是说,不可能通信的一段用TCP,而另一端用UDP.一个完整的网络信息需要一个五元组来标识:协 ...

  2. my-view-isnt-reflecting-changes-ive-made-to-the-underlying-tables

    FROM http://sqlstudies.com/2013/01/20/my-view-isnt-reflecting-changes-ive-made-to-the-underlying-tab ...

  3. POJ 2406 Power Strings KMP运用题解

    本题是计算一个字符串能完整分成多少一模一样的子字符串. 原来是使用KMP的next数组计算出来的,一直都认为是能够利用next数组的.可是自己想了非常久没能这么简洁地总结出来,也仅仅能查查他人代码才恍 ...

  4. Office 365 Certificate Exam Resources

    70-321 Deploying Office 365 Deploying Office 365 Jump Start (01): Infrastructure Planning Deploying ...

  5. sizeof求字节以及与strlen的区别

    例子一: /* *根据以下条件进行计算: *1. 结构体的大小等于结构体内最大成员大小的整数倍 *2. 结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相 ...

  6. 【ZZ】编程能力层次模型

    http://blog.csdn.net/shendl/article/details/43835421 前言 程序员的编程技能随着经验的积累,会逐步提高.我认为编程能力可以分为一些层次. 下面通过两 ...

  7. PAT 1004

    1004. Counting Leaves (30) A family hierarchy is usually presented by a pedigree tree. Your job is t ...

  8. 模板方法模式(Template Method)

    @@@模式定义: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. @@@练习示例:  登录控制 @@@示例代码: \s ...

  9. Helpers\TableBuilder

    Helpers\TableBuilder Table builder helper is a class that would help you to create tables in MySQL ( ...

  10. couldn't set tty to ppp discipline invalid argument

    参考: http://pptpclient.sourceforge.net/howto-diagnosis.phtml#conventions http://blog.chinaunix.net/ui ...