常量、字段和成员属性

来源:互联网 发布:vue.js 视频教程 编辑:程序博客网 时间:2024/05/20 02:51
 
常量、字段和成员属性
常量、字段和成员属性都是类的成员,用于维护类的内容或状态。通常,常量用于从不改变的值;字段用于维护类中的私有数据;成员属性用于控制对类中数据的访问。
 
常量
C#使用const来声明有固定值(不可改变)的变量。
  •   可在一条语句中使用关键字const声明多个常量。
  •   常量必须定义为基本类型。
  •   不能从类实例访问常量。
关于常量,最重要的是,要清楚它的值是在编译时确定的,这一点影响很大,改变常量值需要从新编译DLL,因为const的值是在编译的时候计算的。通常把一组常量存储在一个特殊的工具或辅助类中。要将这些常量声明为public,以便所有类都能访问。由于不需要创建类实例,所以将类声明为abstract。
 
字段
字段也用于在类中存储数据。同const相比,主要有两个不同:它的值在运行时确定,另外类型也不仅限于基本类型。
 
字段修饰符
除访问修饰符外,字段还有另外两个修饰符:static和readonly。
修饰符
定义
static
静态字段是类的状态,而不是类实例的状态。这说明,可以指定classname,fieldname来直接访问字段,而无需创建类实例。从这个角度上讲,静态字段有点类似于常量。
readonly
只读字段只能在声明语句或类结构构造函数中赋值。其效果实际上是将字段变成了一个常量。如果以后代码想要改变字段的值,就会导致错误。
 
对此有一条经验,字段应该定义为pirvate,以保证对象的状态是安全的,外部无法处理。然后根据外部访问的需要,再使用方法和成员属性来获取设置这些私有数据。
如果没有初始化字段,则会将其设置为相应类型的默认值:数值的默认值为0,引用类型的值为null,字符串的值默认为单引号(’’),布尔值默认为false。
有一种情况下将字段设置为public是有意义的:即程序需要一个全局常量时。通过声明字段为public static readonly,可以创建一个运行时常量。
 
成员属性
成员属性(Property)用于控制对类中值的读写访问。Java和C++程序创建成员属性时,需要编写一个存取方法(accessor)来获取字段数据,并编写一个修改方法(mutator)设置字段。与这些语言不同,事实上,C#编译器可以识别一种特殊的成员属性构造,并创建和访问数据提供了一种简化的语法。确切的说,这个语法与相应的C++并没有什么天壤之别,但它确实能使编译器产生更高的执行代码。
语法:
 
 
[attribute] <modifier> <data type> <property name>
{
    [access modifier] 
get
        {
            
return(PropertyValue)
        }
    [access modifier] 
set
        { Code to 
set a field to the keyword value}
}

注意:

  1.    除了4中访问修饰符外,成员属性修饰符可以是static、adstract、new、virtual或override。abstract只用在抽象类中;virtual用在基类中,并且允许子类覆盖该成员属性。
  2.     value是一个隐式的参数,其中包含调用成员属性时传递的值。
  3.   get和set存取方法(获取方法和设置方法)可以有不同的访问修饰符。
创建和访问成员属性
public class Upholstery
{
    
private double YardPrice;

    
public double PricePerYard
    {
        
get { return YardPrice; }
        
set
        {
            
if (value <= 0)
                
throw new ArgumentOutOfRangeException("Price must be greater than 0.");
            YardPrice 
= value;
        }
    }
}
 
代码中的get块相当于传统的存取方法,而set相当于修改方法。包含其中的一个就可以,如果没有get块,成员属性就是只写的,如果没有set块的话,成员属性则为只读。
get块中所有的return语句必须指定一个表达式,而且它能隐式的转换成成员属性的类型。
使用成员属性的效率不一定比直接使用字段的效率低。对于仅包含少量代码的非虚(non-virtual)成员属性类说,JIT编译器可能会用get或set块中的实际代码取代对存取方法的调用。这个过程称为(inlining),可以减少运行时的调用开销。其结果是这些代码与使用字段的代码同样高效,而且灵活的多。
 
 
索引器
索引器(indexer)常常称为参数化成员属性。就像成员属性一样,它在类中声明,实体中可以包含获取和设置方法,这些存取方法与成员属性存取方法的语法相同,但索引器与成员属性有两点不同:它可以接受一个或多个参数,而且使用关键子this作为索引器的名字。其完整语法为:
[attribute] <modifier> <return type> this [property(s)]
 
例子:
class IndexerClass
{
    
private int[] arr = new int[100];
    
public int this[int index]   // Indexer declaration
    {
        
get
        {
            
if (index < 0 || index >= 100){return 0;}
            
else
            {
return arr[index]; }
        }
        
set
        {
            
if (!(index < 0 || index >= 100))
            {arr[index] 
= value; }
        }
    }
}
class MainClass
{
    
static void Main()
    {
        IndexerClass test 
= new IndexerClass();
        test[
3= 256;
        test[
5= 1024;
        
for (int i = 0; i <= 10; i++)
        {
            System.Console.WriteLine(
"Element #{0} = {1}", i, test[i]);
        }
    }
}

 
输出:
Element #0 = 0
Element #1 = 0
Element #2 = 0
Element #3 = 256
Element #4 = 0
Element #5 = 1024
Element #6 = 0
Element #7 = 0
Element #8 = 0
Element #9 = 0
Element #10 = 0
注意:
索引器不支持static修饰符,因为索引器只适用于实例。
索引器的优点在于,它对客户隐藏了数组操作细节,而且在返回值之前,可以完成有效性检查或数据修改。如果对象的成员属性可以表示为集合(而不是标量值),这种情况下索引器最为适用。
 
原创粉丝点击