关于“属性”的几个问题,也许面试会问到哦~

简介:

 

       这些天太忙了都没更新博客了,这篇我们继续聊聊“属性”,大家都知道,属性其实分两种,无参属性和有参属性,顾名思义

无参属性就是我们平时用到的 “属性”,有参属性就是我们所说的 “索引器”,

1     public class Bird
2     {
3         public int Age { get; set; }
4 
5         public string this[int i] { get { return i + string.Empty; } set { ;} }
6     }

乍一看这两个还是蛮像的,本质上来说这两个都是getXXX,setXXX方法,只是编译器为了提高我们的开发效率而做的语法糖。

好,下面回答几个小问题,当然是我自己的个人见解。

 

Q:为什么类型中要存在属性?

A: 一般来说,一个类中都存在一个描述类的状态数据,我们也可以认为是元数据,这些元数据是不可以被轻易修改的,一但

      被错误的修改,就会导致类的破坏,所以建议在字段中加一层壳,由属性来提供高层访问。

   举个例子:Person的Age字段不能设为<0 || >150的非法数据,这个时候我们就可以在属性的set方法上进行过滤了。

private int age;

        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                if (value < 0 || value > 150)
                    throw new Exception();
                age = value;
            }
        }


Q:  我看到上面字段age和属性Age,那么请问自动属性有封装字段吗,比如下面的代码?


1         public int Age
2         {
3             get;
4             set;
5         }

A:其实这个问题问的好,如果你是平时用用而没有用IL看一下的话,可能还真被蒙到了,既然说到了IL,那就用IL看一下。

从IL上可以清楚的看到其实编译器给我们生成了一个私有的k__BackingField 字段。

 

Q: 提到属性,我想问一下“类型初始化器”和“构造函数”有什么区别。


1             var b = new Bird { Name = "youyou", Age = 20 };

A: 要看有没有区别,我们得要看到底这个“类型初始化器”到底干了些什么?老规矩,我们看看IL代码。

从IL上可以看出,两个nop之间,我们调用了构造函数(ctor),并且先后调用了set_Name,set_Age方法,所以本质上来说,

“类型初始化器”只是一个语法糖,跟我们手工在构造函数中初始化一样。

 

Q:我经常看到Session["xxx"],Cookie["xxx"],请问索引器只能用到类的实例上吗?可不可以

     用到类型上?

A:这个问题问的好,其实你可以发现,我们在定义一个索引器的时候,根本就没有定义索引器的名字,而是直接用this,重点

    就在这里,我们知道this表示当前实例的上下文,导致我们的[]只能用到类型的实例上,也就做不了将[]用到类型上。



Q:从上图中看到索引器本质上是get_Item,set_Item,但是我如果自己手工定义了一个

   get_Item造成方法名冲突了,这个怎么办?


1         public string this[int i]
2         {
3             get { return i + string.Empty; }
4             set { ;}
5         }


public class Bird
    {
        public string this[int i]
        {
            get { return i + string.Empty; }
            set { ;}
        }

        //重名了,这个怎么办?
        public string get_Item(int s)
        {
            return string.Empty;
        }
    }

 

A: 这个问题也是蛮有意思的,最常见的做法就是手工修改我们自己定义的方法名,但是我们这里可不可以另辟蹊径呢?我们在写

      WCF的时候,可能会遇到给方法标记别名的情况,然后我们就用OperationContract给方法换一个名字,现在估计就有人想到

     了我是不是也可以给“索引器”加上别名?确实可以这样,在这里我们可以用IndexerName来完成。

1         [IndexerName("Fly")]
2         public string this[int i]
3         {
4             get { return i + string.Empty; }
5             set { ;}
6         }

然后我们再看看IL代码,就这样成功的修改了索引器的方法名。

相关文章
|
6月前
|
前端开发 JavaScript
面试官:请你说一说vuex的五个属性,分别是什么,区别和用途说一下(二)
面试官:请你说一说vuex的五个属性,分别是什么,区别和用途说一下
|
SQL Java 数据库
第一季:8spring支持的常用数据库事务传播属性和事务隔离级别【Java面试题】
第一季:8spring支持的常用数据库事务传播属性和事务隔离级别【Java面试题】
142 0
|
3月前
|
JavaScript
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
这篇文章解释了为什么在Vue中组件的`data`属性必须是一个函数而不是一个对象。原因在于组件可能会有多个实例,如果`data`是一个对象,那么这些实例将会共享同一个`data`对象,导致数据污染。而当`data`是一个函数时,每次创建组件实例都会返回一个新的`data`对象,从而确保了数据的隔离。文章通过示例和源码分析,展示了Vue初始化`data`的过程和组件选项合并的原理,最终得出结论:根实例的`data`可以是对象或函数,而组件实例的`data`必须为函数。
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
|
3月前
|
JavaScript
给原始数据类型加属性和方法为什么不会报错?包装类——阿里面试题
给原始数据类型加属性和方法为什么不会报错?包装类——阿里面试题
|
6月前
|
前端开发
一文搞懂css常用字体属性与背景属性(2),非科班面试之旅
一文搞懂css常用字体属性与背景属性(2),非科班面试之旅
|
JavaScript
「Vue面试题」在vue中为什么data属性是一个函数而不是一个对象
「Vue面试题」在vue中为什么data属性是一个函数而不是一个对象
76 0
|
JavaScript
「Vue面试题」动态给vue的data添加一个新的属性时会发生什么?怎样去解决的?
「Vue面试题」动态给vue的data添加一个新的属性时会发生什么?怎样去解决的?
60 0
|
缓存 JavaScript 前端开发
【Vue】模板语法,插值、指令、过滤器、计算属性及监听属性(内含面试题及毕设等实用案例)上篇
Vue 的模板语法是一种用于在 HTML 中声明式地渲染 Vue 组件的语法。它基于 HTML,并通过特定的模板语法扩展了 HTML。Vue 使用了一种称为 “Mustache” 语法的模板插值来绑定数据到 HTML 元素上。在 Vue 的模板语法中,你可以使用双大括号({{}})将数据绑定到 HTML 元素上,这样数据的值会被动态地替换到相应的位置。 在 Vue 的模板语法中,你可以使用双大括号({{}})将数据绑定到 HTML 元素上,这样数据的值会被动态地替换到相应的位置。
|
存储 JavaScript 前端开发
web前端面试高频考点——Vue3.x升级的重要功能(emits属性、生命周期、多事件、Fragment、移出.async、异步组件写法、移出 filter、Teleport、Suspense...)
web前端面试高频考点——Vue3.x升级的重要功能(emits属性、生命周期、多事件、Fragment、移出.async、异步组件写法、移出 filter、Teleport、Suspense...)
245 0
|
移动开发 JavaScript 前端开发
Vue04路由--SPA+ 使用路由建立多视图单页应用+router-link相关属性+【面试题:js中const,var,let区别】
Vue04路由--SPA+ 使用路由建立多视图单页应用+router-link相关属性+【面试题:js中const,var,let区别】
下一篇
无影云桌面