属性(二)

接口属性

可以在接口上声明属性。以下是接口索引器访问器的示例:

public interface ISampleInterface

{

    // Property declaration:

    string Name

    {

        get;

        set;

    }

}

接口属性的访问器不具有体。因此,访问器的用途是指示是否为读写、只读或只写。

示例

在此例中,接口IEmployee具有读写属性Name和只读属性CounterEmployee类实现IEmployee接口并使用这两种属性。程序读取新雇员的姓名和雇员的当前编号,并显示雇员姓名和计算机所得的雇员编号。

可以使用属性的完全限定名,它引用声明成员的接口。例如:

string IEmployee.Name

{

    get { return "Employee Name"; }

    set { }

}

这被称为显式接口实现。例如,如果Employee类实现两个接口ICitizenIEmployee,并且两个接口都具有Name属性,则需要显式接口成员实现。即,如下属性声明:

string IEmployee.Name

{

    get { return "Employee Name"; }

    set { }

}

IEmployee接口上实现Name属性,而下面的声明:

string ICitizen.Name

{

    get { return "Citizen Name"; }

    set { }

}

ICitizen接口上实现Name属性。

interface  IEmployee {
        
string Name{
                
get;
                
set;
            }

        
        
int Counter{
                
get;
            }

    }

    
public   class  Employee : IEmployee {
        
public static int numberOfEmployees;
        
        
private string name;
        
public string Name{        //read-write instance property
                get{
                        
return name;
                    }

                
                
set{
                        name 
= value;
                    }

            }

        
        
private int counter;
        
public int Counter{        //read-only instance property
                get{
                        
return counter;
                    }

            }

        
        
public Employee(){        //constructor
                counter = ++counter + numberOfEmployees;
            }

    }


class  TestEmployee2 {
        
static void Main(){
                System.Console.Write(
"Enter number of employees: ");
                Employee.numberOfEmployees 
= int.Parse(System.Console.ReadLine());
                
                Employee e1 
= new Employee();
                System.Console.Write(
"Enter the name of the new employee: ");
                e1.Name 
= System.Console.ReadLine();
                
                System.Console.WriteLine(
"The employee information:");
                System.Console.WriteLine(
"Employee number: {0}",e1.Counter);
                System.Console.WriteLine(
"Employee name: {0}",e1.Name);
            }

    }


 

非对称访问器可访问性

属性或索引器的getset部分称为“访问器”。默认情况下,这些访问器具有相同的可见性或访问级别:其所属属性或索引器的可见性或访问级别。不过,有时限制对其中某个访问器的访问会很有用。通常是在保持get访问器可公开访问的情况下,限制set访问器的可访问性。例如:

public string Name

{

    get

    {

        return name;

    }

    protected set

    {

        name = value;

    }

}

在此示例中,名为Name的属性定义了一个get访问器和一个set访问器。Get访问器接受该属性本身的可访问性级别(在此例中为public),而对于set访问器,则通过对该访问器本身应用protected访问修饰符来进行显式限制。

对属性或索引器使用访问修饰符受以下条件的制约:

l         不能对接口或显式接口成员实现使用访问器修饰符

l         仅当属性或索引器同时具有setget访问器时,才能使用访问器修饰符。这种情况下,只允许对其中一个访问器使用修饰符

l         如果属性或索引器具有override修饰符,则访问器修饰符必须与重写的访问器的访问器(如果有的话)匹配

l         访问器的可访问性级别必须比属性或索引器本身的可访问性级别具有更严格的限制

 

重写访问器的访问修饰符

在重写属性或索引器时,被重写的访问器对重写代码而言,必须是可访问的。此外,属性/索引器和访问性级别都必须与相应的被重写属性/索引器和访问器匹配。例如:

public class Parent

{

    public virtual int TestProperty

    {

        // Notice the accessor accessibility level.

        protected set { }

 

        // No access modifier is used here.

        get { return 0; }

    }

}

public class Kid : Parent

{

    public override int TestProperty

    {

        // Use the same accessibility level as in the overridden accessor.

        protected set { }

 

        // Cannot use access modifier here.

        get { return 0; }

    }

}

实现接口

使用访问器实现接口时,访问器不能具有访问修饰符。但是,如果使用一个访问器(get)实现接口,则另一个访问器可以具有访问修饰符,如下面的示例所示:

public interface ISomeInterface

{

    int TestProperty

    {

        // No access modifier allowed here

        // because this is an interface.

        get;  

    }

}

 

public class TestClass : ISomeInterface

{

    public int TestProperty

    {

        // Cannot use access modifier here because

        // this is an interface implementation.

        get { return 10; }

 

        // Interface property does not have set accessor,

        // so access modifier is allowed.

        protected set { }

    }

}

访问器可访问性域

如果对访问器使用访问某个修饰符,则访问器的可访问性域由该修饰符确定。

如果不对访问器使用访问修饰符,则访问器的可访问性域由属性或索引器的可访问性级别确定。

示例

下面的示例包含三个类:BaseClassDerivedClassMainClass。每个类的BaseClassNameId都有两个属性。该示例演示在使用限制性访问修饰符(protectedprivate)时,如果通过BaseClassId属性隐藏DerivedClassId属性。因此,向该属性赋值时,将调用BaseClass类中的属性。将访问修饰符替换为public将使该属性可访问。

该示例还演示了DerivedClassName属性的set访问器上的限制性访问修饰符(privateprotected)如何防止对该访问器的访问,并在向它赋值时生成错误。

public   class  BaseClass {
        
private string name = "Name-BaseClass";
        
private string id = "ID-BaseClass";
        
        
public string Name{
                
get{
                        
return name;
                    }

                
set{
                    }

            }

        
        
public string Id{
                
get{
                        
return id;
                    }

                
set{
                    }

            }

    }


public   class  DerivedClass : BaseClass {
        
private string name = "Name-DerivedClass";
        
private string id = "ID-DerivedClass";
        
        
new public string Name{
                
get{
                        
return name;
                    }

                
//using "protected" would make the set accessor not accessible
                set{
                        name 
= value;
                    }

            }

            
            
//using private on the following property hides it in the Main Class.
            
//Any assignment to the property will use Id in BaseClass.
            new private string Id{
                    
get{
                            
return id;
                        }

                    
set{
                            id 
= value;
                        }

                }

    }


class  MainClass {
        
static void Main(){
                BaseClass b1 
= new BaseClass();
                DerivedClass d1 
= new DerivedClass();
                
                b1.Name 
= "Mary";
                d1.Name 
= "John";
                
                b1.Id 
= "Mary123";
                d1.Id 
= "John123";        //The BaseClass.Id property is called.
                
                System.Console.WriteLine(
"Base: {0}, {1}",b1.Name,b1.Id);
                System.Console.WriteLine(
"Derived: {0}, {1}",d1.Name,d1.Id);
            }

    }


如何:声明和使用读/写属性

属性可以提供公共数据成员的便利,而又不会带来不受保护、不受控制以及未经验证访问对象数据的风险。这是通过“访问器”来实现的:访问器是为基础数据成员赋值和检索其值的特殊方法。使用set访问器可以为数据成员赋值,使用get访问器可以检索数据成员的值。

此示例演示Person类,该类具有两个属性:Name(string)Age(int)。这两个属性都提供getset访问器,因此它们被视为读/写属性。

class  Person {
        
private string m_name = "N/A";
        
private int m_Age = 0;
        
        
//Declare a Name property of type string:
        public string Name{
                
get{
                        
return m_name;
                    }

                
set{
                        m_name 
= value;
                    }

            }

        
        
//Declare an Age property of type int:
        public int Age{
                
get{
                        
return m_Age;
                    }

                
                
set{
                        m_Age 
= value;
                    }

            }

        
        
public override string ToString(){
                
return "Name = " + Name + ", Age = " + Age;
            }

    }


class  TestPerson {
        
static void Main(){
                
//Create a new Person object:
                Person person = new Person();
                
                
//Print out the name and the age associated with the person:
                System.Console.WriteLine("Person details - {0}",person);
                
                
//Set some values on the person object:
                person.Name = "Joe";
                person.Age 
= 99;
                System.Console.WriteLine(
"Person details - {0}",person);
                
                
//Increment the Age property:
                person.Age += 1;
                System.Console.WriteLine(
"Person details - {0}",person);
            }

    }


可靠编程

在上面的示例中,NameAge属性是公共的,并且同时包含getset访问器。这允许任何对象读写这些属性。不过,有时需要排除其中的一个访问器。例如,省略set访问器将使该属性称为只读的:

public string Name

{

    get

    {

        return m_name;

    }

}

此外,您还可以公开一个访问器,而使另一个访问器称为私有的或受保护的。

声明了属性后,可像使用类的字段那样使用这些属性。这使得获取和设置属性值时都可以使用非常自然的语法,如以下语句只能够所示:

person.Name = "Joe";

person.Age = 99;

注意,属性set方法中可以使用一个特殊的value变量。该变量包含用户指定的值,例如:

m_name = value;

请注意用于使Person对象上的Age属性递增的简介语法:

person.Age += 1;

如果将单独的setget方法用于模型属性,则等效代码可能类似于:

person.SetAge(person.GetAge() + 1);

本示例中重写了ToString方法:

public override string ToString()

{

    return "Name = " + Name + ", Age = " + Age;

}

注意,程序中未显示使用ToString。默认情况下,它由WriteLine调用来调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值