2017-07-26关于set和get访问器以及value的理解

 1     class TestA
 2     {
 3         private int? app;//这是字段
 4         public int APP//这是属性
 5         {
 6             get//get和set类似于一种函数,原本是为访问一个类的私有成语服务的
 7             {
 8                 int tempApp = app * 10 ?? 1;
 9                 return tempApp;
10             }
11             set
12             {
13                 app = value;
14             }
15         }
16 
17 
18         private int obs;
19         public int OBS
20         {
21             get
22             {
23                 return obs;
24             }
25             set//这里旨在说明无论是get还是set都可以含有逻辑处理
26             {
27                 //value是传过来的值,上面也说过get和set类似于一个函数
28                 //那么“demo.OBS = -10”可以理解成形参是value,这是被赋予了-10这个数字,调用“set函数”
29                 if (value < 0)
30                 {
31                     obs = value * -1;
32                 }
33                 else
34                 {
35                     obs = value;
36                 }
37             }
38         }
39     }
40 
41     class Program
42     {
43         static void Main(string[] args)
44         {
45             TestA demo = new TestA();
46             Console.WriteLine("一开始demo.APP为空,调用get后的判空逻辑后为:{0}", demo.APP);
47             demo.APP = 10;
48             Console.WriteLine("赋值语句:demo.APP = 10,调用set。。。。\n" +
49                 "              此时私有成员demo.app的值为10;");
50             Console.WriteLine("上面已经为demo.APP赋值,实际是对demo.app赋值,此时调用get后的乘10逻辑为:{0}", demo.APP);
51 
52             Console.WriteLine("\n==================华丽的分割线===================\n");
53 
54             Console.WriteLine("这里调用demo.OBS的get,应该是int的默认值:{0}", demo.OBS);
55             demo.OBS = -10;
56             Console.WriteLine("赋值语句:demo.OBS = -10,调用set。。。。。。\n" +
57                 "              此时私有成员demo.app的值已经是10;");
58             Console.WriteLine("经过上面的赋值,此时的demo.OBS为:{0}", demo.OBS);
59             Console.ReadKey();
60         }
61     }

 

额,本来想先写这段说明的,奈何弄了代码后无法把代码块下调,就只好写在代码后了~

 

C#入门的书看了不少,属性和字段的区别理解了很久感觉还是没底,我个人的理解是属性会带上访问器,而字段和C++类中的属性是一个意思。那为什么C#会字段属性不同呢?我理解的原因是,用C++举例子,属性的访问权限往往都是私有的,如果我们要访问它们,通常的做法是写对应的SetXxx()和GetXxx()函数,这会很麻烦,因此C#就有了这个语法糖(我姑且当它是语法糖了,不知道这么理解会不会有偏差)。关于这方面的只是,我觉得应该是不难,只是可能我还没有跳出C++固有的限制,所以心里老觉得怪怪的,也无心吸收书中的知识。欢迎大家指正和赐教,本文不是探讨这个问题。说说另一个这方面困扰我的一个问题,那就是set访问器中的value是什么鬼。

 

很多书上介绍set和get往往都是从它的历史演变介绍,典型的就是

private int _tra;
public int Tra
{
        get
        {
            return _tra;
        }
        set
        {
            tra = value;
        }
}

然后慢慢地演变成连private字段都没有了,直接一个public并且get和set直接public int Tra{get; set;},其实这样会让新人感到一头雾水,究竟这个set和get有何用,毕竟都已经是public了,可以直接存取了,何必写get和set呢?

 

再者,我一直的惯性思维是重写get访问器的多,set的少(书上的例子数量也就是给人这样的感觉),所以这个value有什么用?set里究竟能不能写逻辑?

 

其实根本是要弄清楚get和set的作用,就拿这个_tra做例子:

get顾名思义就是得到,也就是“取”,取出这个值的意思。那么什么时候需要取出这个值?当然就是这个属性作为表达式的右值,例如a = Tra,这样a要想得到值,是不是应该取出Tra这个值然后赋给a呢。相反的set就是设置,也就是给这个属性赋值,那它当然是作为表达式的左值了,例如Tra = a。

用函数的思维去想这个事情,我们假设set和get就是函数,get函数通过名字我们第一反应应该是“得到什么”的意思,因此这个函数里是不是应该有一句return呢?而set函数是设置什么的意思,那么是不是应该传个参数让它知道设成什么呢?这就是value的作用。

其实不要脱离当初发明set和get的原因去想这件事,我之所以比喻成函数是因为以往在C++我们就是要写SetXxx()和GetXxx()函数访问私有成员,而GetXxx()函数确实肯定有返回值,SetXxx()一般都有参数,这就是get和set访问器的雏形嘛。只不过因为要好看,而且大多时候SetXxx()也就传递一个参数而已,因此C#为了简洁美和方便使用,就搞了一个value的关键字,其实相当于SetXxx()函数的参数。这个value和形参一样都共同的特点就是不会改变,不影响调用方。实际上我们也不会去修改value的值(但它是允许被修改的)

 

下面是开始代码的运行结果~

运行结果

 

观看value究竟是什么鬼,我在第29行设置了一个断点进行调试,可以理解成就是一个形参。只不过函数调用的方法和真正的函数调用不太一样。

插入断点窥探value

 

 

关于正式的说明,可以参考官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/value

posted @ 2017-07-27 00:27  辣条小布丁  阅读(464)  评论(0编辑  收藏  举报