delphi&.net学习记事本

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
21)类的属性,又称智能字段
using System;
class A
{
    
private int x;
    
public int y;
    
private string s;
    
public int X
    {
        
//get { return this.x; }  //被读
        set { this.x = value; } //被写(将get注释掉的话,就成了只写,这里能灵活很多)
    }
    
public string S
    {
        
get
        {
            
return s;
        }
        
set
        {
            
if (value.Length <= 10)           //只当要赋值的字符串小于10字节时赋值
                s = value;
            
else
                Console.WriteLine(
"Error!");    //否则输出错误
        }
    }
}
class App
{
    
public static void Main()
    {
        A a 
= new A();
        a.y 
= 100;              //直接写y
        Console.WriteLine(a.y); //直接读y
        a.X = 200;              //通过x的存取器x写
        
//  Console.WriteLine(a.X); //读操作被限制掉了,但是没有使用readonly关键字
        
//向字段s赋值
        a.S = "12345678912345";//虽然进行了赋值操作,但是条件不符合,a.S并没有被真正赋值
        Console.WriteLine("a.S = "+a.S);
        a.S 
= "123";            //当符合条件时,才真正赋值了
        Console.WriteLine("a.S = " + a.S);
        Console.Read();
    }
}
//例32:异常处理
using System;
//将两个数相加,如果大于100则返回错误,而异常处理的话则抛出异常
class App
{

    
static int Add(int x, int y)  //异常处理方法
    {
        
if ((x + y) > 100)
            
throw new Exception("失败,超过100拉!");   //抛出异常
        return x + y;
    }
    
public static void Main()
    {
        
try
        {            
            Console.WriteLine(Add(
992));
        }
        
catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        Console.Read();
    }
}
23)接口与接口组合
using System;

interface IA  //这里声明了一个接口,有一个方法showIA;
{
    
void showIA();
}
interface IB    //接口IB声明了showIB.
{
    
void showIB();
}
interface IC : IA, IB  //接口IC是IA,IB的组合,加上本身的定义.
{
    
void showIC();
}
//类A包含了以上接口的具体实现
class A : IC            //由于IC是IA和IB的组合,在声明IC时,隐式声明了IA和IB与类的联系
{
    
public void showIA()
    {
        Console.WriteLine(
"showIA");
    }
    
public void showIB()
    {
        Console.WriteLine(
"showIB");
    }
    
public void showIC()
    {
        Console.WriteLine(
"showIC");
    }

}
class App
{
    
static void Main(string[] args)
    {
        A a 
= new A();//接口的使用,必须先创建接口关联的类的实例!

        IA ia 
= a; 
        ia.showIA();
        Console.WriteLine(
"-------------------------");
        IB ib 
= a;
        ib.showIB();
        Console.WriteLine(
"-------------------------");
        IC ic 
= a;
        ic.showIA();
        ic.showIB();
        ic.showIC();
        Console.Read();
    }
}
24)checked/unchecked:使用checked后,溢出会抛出异常;unchecked后,溢出部分被自动截掉而不抛出异常
using System;

class Test
{
    
static int x = 1000000;
    
static int y = 1000000;
    
public static int F()
    {
        
return checked(x * y);    //如果有溢出,则抛出异常.
    }
    
public static int G()
    {
        
return unchecked(x * y);    //如果有溢出,则截掉高出部分
    }
    
public static int H()
    {
        
return (x * y);    //如果有溢出,依赖于编译时的默认情况
    }
}
class App
{
    
public static void Main()
    {
        Console.WriteLine(Test.H());
        Console.WriteLine(Test.G());
//先unchecked,溢出不抛出异常
        Console.WriteLine(Test.F());//直到这一步,才抛出异常
        Console.Read();
    }
}
25)C#事件"发布"-"预订"机制的核心内容:代表,事件类,发布事件类,预订事件类.
using System;
using System;
//本质是:发布事件类A声明了本类的关联的事件类型P,而预定事件类B则对此事件P做出敏感声明,这两个类有其必然的内在联系.当类A
//发生了事件P时,对事件P敏感的类B就马上对此事件作出处理.
/*
  步骤:
 * 1)首先是具体的事件类的定义.事件类型有很多,我们需要定制一个满足描述问题的事件类型,必须从EventArgs基类继承.
 * 2)我们将此定制好的事件与类A关联起来,好象是类A"发布"了这样的一个事件,并在适当的时候自动调用对此事件敏感的方法(不管是类内还是类外.)
 * 3)一个对此事件敏感的类B对此事件做出"预订"动作,并定义了具体的处理事件的方法,在事件触发时,调用此事件处理方法根据具体事件发生信息处理事件.
 * 4)而实现事件隐式触发调用的手段就是"代表!".
 
*/
//"事件发布者"负责声明"事件类型"及触发事件;"事件预订者"负责预订事件并具体定义事件处理方法.

//声明代表:代表仅仅也只是一个类型安全的函数指针.只不过声明的方式与C++的不同.
public delegate void MyHandler(object sender, MyEventArgs e);

public class MyEventArgs : EventArgs    //事件类型声明:这个事件类十分关键,它是"事件发布者"和"事件预订者"之间联系的纽带.
{
    
//在事件类内部,一般都会使用一些参数信息来完善对具体事件的描述,当然也可以没有参数,不过这样的话,显然事件只能有一个处理条件
    public string m_id;
}
//"发布"事件.(发布事件的类,仅仅只是"声明"了本类关联的一个事件类型,而没有规定本类必须有处理此事件的处理方法
class A
{
    
//Event是一个代表实例化对象,即可以调用所有与其定义的函数类型相同的所有方法.即使用event关键字声明也不能改变这一点
    
//并且,event只是一个附加的条件声明,说明此Event对象对应的方法是事件处理方法,具有编译器统一规定的格式.
    public event MyHandler Event;
    
public void FireEvent(MyEventArgs e)   //这一方法将事件类型与特定的类关联起来,即类"发布"事件.
    {
        
if (Event != null)
        {                               
//这里,代表对象调用了其他类的方法.C#的代表,是一种实现事件"发布""预订"机制的手段
            Event(this, e);             //触发事件.(即隐式调用"预定"事件的类的方法)
        }
    }
}
//"预订"事件的类,必须定义响应事件的事件处理方法.
class B
{
    
public const string m_id = "Class A";
    
//OnHandler1和OnHandler2这两个方法是对具体MyEventArgs事件类型的的处理方法.
    public void OnHandler(object sender, MyEventArgs e)
    {
        Console.WriteLine(
"I am in OnHandler1 and MyEventArgs is {0}", e.m_id);
    }

    
//创建代表对象,并事件处理函数包含在其中同时设置好将要触发事件的对象
    public B(A a)
    {
        MyHandler d 
= new MyHandler(OnHandler);
        a.Event 
+= d;
    }
}
//关键在于事件类型类的定义上."发布"事件的类与"预订"事件的类彼此是通过中间的"事件类型类"来发生间接关联,并不直接关联.
public class Driver
{
    
public static void Main()
    {
        A a 
= new A();
        B b 
= new B(a);
        MyEventArgs e 
= new MyEventArgs();//事件类对象.
        e.m_id = "Event args for event 1";
        a.FireEvent(e);
        Console.Read();
    }
}
26)C#事件继续
using System;

public delegate void MyHandler(object sender, MyEventArgs e);//一个普通的委托声明

public class MyEventArgs : EventArgs        //事件类
{
    
public string m_id;
}
class A
{
    
public event MyHandler Event;         //发布事件

    
public void FireEvent(MyEventArgs e)  //触发事件
    {
        
if (Event != null)                
        {
            Event(
this, e);              //在触发的事件中,调用所有绑定的事件处理方法
        }
    }
}
//事件发布者A:他有其一个专门处理调用事件处理方法的委托对象,这个委托对象能

class B
{
    
//传递来的类A对象a,在方法内改变的会直接影响到传递来的对象,这点与C++不同.这是一个注意的地方.
    public B(A a)       //预订事件.
    {
        MyHandler d 
= new MyHandler(OnHandler);
        a.Event 
+= d;//a.Event和d都是MyHandler委托对象,通过相加,可以使此
    }

    
public void OnHandler(object sender, MyEventArgs e)//事件处理方法.(被隐式调用.)
    {
        Console.WriteLine(
"类B的事件处理:{0}", e.m_id);
    }
}
//这里,我们将再增加一个预定MyEventArgs事件的类C
class C
{
    
//传递来的类A对象a,在方法内改变的会直接影响到传递来的对象,这点与C++不同.这是一个注意的地方.
    
//预订事件:其实使一个类预定事件的方法有很多,本质只要使要预定事件的类的事件处理方法加到发布事件的类的事件委托对象中即可(这是利用了委托的特性!)
    
//但是,一个事件发布者是固定的,而事件预订者却有可能随时改变,所以,这项工作交给了事件预订者来处理.
    public C(A a)
    {
        MyHandler d 
= new MyHandler(OnHandler);
        a.Event 
+= d;//a.Event和d都是MyHandler委托对象,通过相加,可以使此
    }

    
public void OnHandler(object sender, MyEventArgs e)//事件处理方法.(被隐式调用.)
    {
        Console.WriteLine(
"类C的事件处理:{0}", e.m_id);
    }
}
public class App
{
    
public static void Main()
    {
        A a 
= new A();  //a是事件发布者
        B b = new B(a); //b是事件预定者
        MyEventArgs e = new MyEventArgs();//事件对象e中具体包含了事件的信息,我们从事件发布者对象那传递到事件预定者对象.
        e.m_id = "Event args for event";    //这使对事件信息的具体描述
        a.FireEvent(e); //触发FireEvent方法后,这时调用的只是一个类B的事件处理方法.
        Console.WriteLine("-----------------------------");
        
//下面我们增加一个类C的事件处理方法
        C c = new C(a); //这一步,将类C发事件处理方法指针加到了a的委托函数指针列表上.
        a.FireEvent(e);//这一行,将同时调用类B和类C的事件处理方法.再多也一样!
        Console.Read();
    }
}
27)C#事件继续
using System;

public delegate void MyHandler(object sender, MyEventArgs e);    //一个事件委托(即特定的函数指针)

public class MyEventArgs : EventArgs    //自定义事件类(自定义异常类)
{
    
public string m_id;
}

class A
{
    
public event MyHandler Event;        //事件对象,其实就是一个委托,不断将各个方法挂到此委托链上
    public void FireEvent(MyEventArgs e)
    {
        
if (Event != null)
        {
            Event(
this, e);
        }
    }
}

class B
{
    
public void OnHandler(object sender, MyEventArgs e)
    {
        Console.WriteLine(
"我是 B 的事件处理方法:" + e.m_id);
    }
}

public class Driver
{
    
static void OnHandler(object sender, MyEventArgs e)
    {
        Console.WriteLine(
"我是 Driver 的事件处理方法:" + e.m_id);
    }
    
static event MyHandler my;
    
public static void Main()
    {
        my 
+= new MyHandler(OnHandler);     //我们所做的就是把方法挂到委托链是
        B b = new B();

        my 
+= new MyHandler(b.OnHandler);
        MyEventArgs e 
= new MyEventArgs();
        e.m_id 
= "!哇哈哈!";
        my(
new Driver(), e);
        Console.WriteLine(
"-----------------------------------");


        A a 
= new A();      //这里将委托链传递给了类A的委托,由类A进行调用
        a.Event += my;
        a.FireEvent(e);

        Console.Read();
    }
}
28)索引器
using System;
//索引器允许类或结构的实例按照与数组相同的方式进行索引.
//索引器类似于属性,不同之处在于它们的访问器采用参数

class A
{
    
private int x = 100;
    
private string y = "haha";  
    
public object this[int i]
    {
        
get
        {
            
switch (i)
            {
                
case 0:
                    
return x;
                
case 1:
                    
return y;
                
default:
                    
throw new Exception("没有合适的索引范围.");
            }           
        }
        
set
        {
            
switch (i)
            {
                
case 0:
                    x 
= Convert.ToInt32(value);
                    
break;
                
case 1:
                    y 
= Convert.ToString(value);
                    
break;
                
default:
                    
throw new Exception("没有合适的索引范围.");
            }
        }
    }
}

class Program
{
    
static void Main(string[] args)
    {
        A a 
= new A();
        a[
0= 1;
        a[
1= "lalala";
        Console.WriteLine(a[
0]);
        Console.WriteLine(a[
1]);
        Console.Read();
    }
}
/*
    索引器使得对象可按照与数组相似的方法进行索引。
    get 访问器返回值。set 访问器分配值。
    this 关键字用于定义索引器。
    value 关键字用于定义由 set 索引器分配的值。
    索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。
    索引器可被重载。
    索引器可以有多个形参,例如当访问二维数组时。
 
*/
posted on 2006-11-16 11:24  骑人的驴  阅读(443)  评论(0编辑  收藏  举报