C#之属性总结

属性是一种类的成员,它的实现类似函数,访问类似字段。它的作用是提供一种灵活和安全的机制来访问,修改私有字段。所以属性必须依赖于字段。

或许有人说诸如:public  string str{get;set}这种自动属性不需要依赖字段。其实这只是表面现象,编译器会只是为了图个我们方便,但是它会创建一个private,anonymous, backing field(私有的匿名支持字段),该字段只能通过属性的get,set访问器来访问。

private int dd;
public int dd
{
	get{ return xx*3;}
	set{ xx = value/3;}
}

没有set的属性是一种只读属性,没有get的访问器是一种只写属性。
(1) get访问器用来返回字段或者计算 并返回字段,它必须以return或者throw终结。
    private string name;
    public string Name
    {
        get
        {
            return name != null ? name : "NA";
        }
    }
(2) set访问器类似返回类型为void的函数,使用value的隐式参数
private string name;  // the name field
    public string Name    // the Name property
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }
(3) 访问器的限制
属性访问标记可以为public,private,protected,internal,protected internal,因为访问器的访问限制必须比属性的访问限制更加严格,所以
 	private int xx;
        public int sxx
        {
            public get { return xx; }//error
            set { xx = value; }
        }

不能对接口或者显式的接口使用访问修饰符,因为接口里里面所有的默认是public的;
同时具有get,set访问器时,才允许使用访问修饰符,并且只能有一个使用;
如果属性有override修饰的时候,访问器修饰符必须与被重写的匹配。
访问器的可访问级别必须比属性的可访问级别更加严格

理解:

首先第四条最容易想到,也是很合理的,毕竟是外围的决定内部的。

其次,既然第四条可以理解,那么如果只有一个访问器的时候,访问器访问级别等同属性,如果这个时候再去指  定更加严格的访问级别,那么为何不当初在属性上指定呢?

      这条理解了,那么为什么必须同时具有get,set才能添加访问修饰符就更加明确了。


推理:

接口中属性是public的,那么如果接口中只有一个get或者set的时候,我们可以在继承中指明另一个访问器的属   性。但是如果接口中同时具有get,set,那么按照派生和继承的匹配性,这时候就不能这样再指定访问器的访问限制了。

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 { }
    }
}

(4)可以用static 修饰属性,以便随时访问
private static int counter;
public static int Counter
    {
        get { return counter; }
    }
(5)属性隐藏
public class Employee
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}


public class Manager : Employee
{
    private string name;


    // Notice the use of the new modifier:
    public new string Name // use new to hide property in base class
    {
        get { return name; }
        set { name = value + ", Manager"; }
    }
}

(6)virtual来修饰属性,派生类使用override来重写属性
public class Parent
{
    public virtual int TestProperty
    {
      
        protected set { }
        get { return 0; }
    }
}
public class Kid : Parent
{
    public override int TestProperty
    {
        protected set { }
        get { return 0; }
    }
}

(7) abstract 修饰属性,派生类来实现属性
abstract class Shape
{
    public abstract double Area
    {
        get;
        set;
    }
}


class Square : Shape
{
    public double side;
    public override double Area
    {
        get
        {
            return side * side;
        }
        set
        {
            side = System.Math.Sqrt(value);
        }
    }
}

(8)sealed 修饰属性,派生类不能修改属性

(9)接口属性
接口属性不具有函数体
public interface Inters
{
	string Name
	{	
		get;
		set;
	}
}

(10) 自动属性
当属性访问器中不需要其他访问逻辑时候,就可以使用自动属性,使代码更加简洁
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }


(11)"Process is terminated due to StackOverflowException." 异常产生的原因

        public string Position
        {
            get { return null; }
            set { Position = value; }
        }

像这样的代码,可能是初学者写的,它编译的时候没有问题,但是一旦运行起来就出问题,抛出"Process is terminated due to StackOverflowException."的异常。

原因其实很简单,属性用起来像字段,但是它的本质是函数,上面的属性定义

Position = value;

处出现了递归,这样的确在使用属性的时候就会出现无穷次自己调用自己,从而导致了栈溢出,这再次说明了属性必须依托于字段。



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值