从C/C++到C# (4)

    本篇主要描述了C#PropertyIndexer的使用,在保证数据封装性和安全性的情况下,使得用户可以象fieldarray一样访问被封装的数据,提高程序的可读性。

  • Properties允许你在保持classfield封装性的前提下使用public field-like语法访问;Property是介于logical fieldphysical method之间的功能,甚至可以脱离实际的field

struct ScreenPosition

{

    public ScreenPosition(int X, int Y)

    {

        this.x = rangeCheckedX(X);

        this.y = rangeCheckedY(Y);

    }

    public int X

    {

        get { return this.x; }

        set { this.x = rangeCheckedX(value); }

    }

    public int Y

    {

        get { return this.y; }

        set { this.y = rangeCheckedY(value); }

    }

    private static int rangeCheckedX(int x) { ... } 

    private static int rangeCheckedY(int y) { ... } 

    private int x, y;

}

ScreenPosition origin = new ScreenPosition(0, 0);

int xpos = origin.X;

int ypos = origin.Y;

  • 数值通过value变量传递到set访问符;可以定义staticproperty;可以定义只含有get访问符的只读property;可以定义只含有set访问符的只写propertygetset访问符可以具有不同的访问等级(只能设置启动的一个),但是都必须不高于property的整体访问等级。
  • Property和实际的field相比也具有局限性:不能通过set访问符进行初始化;property不能作为ref/out参数;不能定义constproperty
  • Interfaces中也可以描述property,在实现这个接口的class/struct中去实现这些访问符;如果你是通过class实现interface中的property,还可以将实现声明成virtual的。

interface IScreenPosition

{

    int X { get; set; }

    int Y { get; set; }

}

struct ScreenPosition : IScreenPosition

{

    ...

    public int X

    {

        get { ... }

        set { ... }

    }

    public int Y

    {

        get { ... }

        set { ... }

    }

    ...

}

class ScreenPosition : IScreenPosition

{

    ...

    public virtual int X

    {

        get { ... }

        set { ... }

    }

    public virtual int Y

    {

       get { ... }

       set { ... }

    }

    ...

}

  • 如果你使用explicit interface implementation来实现property,这个实现就必须是non-publicnon-virtual的。

struct ScreenPosition : IScreenPosition

{

    ...

    int IScreenPosition.X

    {

        get { ... }

        set { ... }

    }

    int IScreenPosition.Y

    {

        get { ... }

        set { ... }

    }

    ...

    private int x, y;

}

  • Property适用于访问单一数值的field,如果需要访问具有多个数值的field,就可以使用indexer;Indexer可以看作smart array,而property可以看做smart field;一个class/struct只能包含一个indexer;要访问的下标通过index变量传入。

struct IntBits

{

    public IntBits(int initialBitValue)

    {

        bits = initialBitValue;

    }

    public bool this [ int index ]

    {

        get 

        {

            return (bits & (1 << index)) != 0; 

        }

        

        set 

        {

            if (value)  // Turn the bit on if value is true, otherwise turn it off

                bits |=  (1 << index);

            else

                bits &= ~(1 << index);

        }

    }

    private int bits;

}

int adapted = 63;

IntBits bits = new IntBits(adapted);

bool peek = bits[6];  // retrieve bool at index 6

bits[0] = true;       // set the bit at index 0 to true

bits[31] = false;     // set the bit at index 31 to false

  • 你可以定义staticProperty,但是不能定义staticindexer,你可以定义只包含set或者get访问符的indexer
  • Indexer可以使用非数字的下标,Array只能适用整数下标;Indexer可以被重载,Array不能;Indexer不能作为ref/out参数,Array元素可以。
  • 你可以在interface中声明indexer,让继承这个接口的class/struct来实现indexer;如果你是通过class实现interface中的indexer,还可以将实现声明成virtual

interface IRawInt

{

    bool this [ int index ] { get; set; }

}

struct RawInt : IRawInt

{

    ...

    public bool this [ int index ]

    {

        get { ... }

        set { ... }

    }

    ...

}

class RawInt : IRawInt

{

    ...

    public virtual bool this [ int index ]

    {

        get { ... }

        set { ... }

    }

    ...

}

  • 如果你使用explicit interface implementation来实现indexer,这个实现就必须是non-publicnon-virtual的。

struct RawInt : IRawInt

{

    ...

    bool IRawInt.this [ int index ]

    {

        get { ... }

        set { ... }

    }

    ...

}

(待续,下一篇将描述C#DelegateEvent的使用,说明C#中传递和处理事件的机制)  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值