关于“参数”的几个问题,也许面试会问到哦~
? ? ?这篇继续聊聊 ”参数“的一些话题,我们知道参数大概有”默认参数“,”可选参数“,”ref参数“,”out参数“以及”可变参数“。 下面提几个小问题,可能在面试中会被问到。
Main( k =
Run(k++,k++,k++
Run( i, j,
}
不管这个问题算不算小儿科,既然被问到了,并且又是在参数这个博文里面,当然要么直接加等于2,要么就是0,如果你在 ? ? 局部代码区域直接写k++,那么毫无疑问的就是k=k;k=k+1,也就是先赋值再自增,那如果作为参数的话,还是一样吗? ? ? 答案当然就在IL里面。 ? ? 从IL上我们看的很清楚,即使++操作是作为参数的形式,也是依次执行了三个add,然后add完之后再call我们的run方法。 最后得到结果毫无疑问就是2了。
Run( i =
}
可以这么说的,我们知道C#有一个限制,就是默认值必须是编译时就能确定的常量值,既然是常量值,那么这个值就一定 ? ? 会嵌入到程序集的元数据中,老规矩,继续看下生成的IL代码。 如果你仔细观察,你会发现有两个不同的地方。 ①:参数列表中的opt,这个参数其实就是编译器给该参数打上了OptionalAtrribute标记,既然是特性,它也会嵌入到程序集 ? ? ?的元数据中,下面看下它的源代码会发现没什么有价值的地方,就是标记这个参数是不是可选的。 ② 我们会发现有一个param参数,其实这个参数就是编译器给参数打上的一个默认值的标记,继续看下源代码。 这里我们发现有一个构造函数,需要传递一个默认值,而这个默认值取自我们定义的常量值,也就是4. 所以综合来说,确实是一块语法糖,其实真实的代码应该是这样,只是赋值操作给了编译器。 Run( i =
}
Main( Add( [] { ,,
AddRange(,
Add(
AddRange(
}
确实在add的场景下语意大增了不少,同时也让我少写了一些代码,那么到底param是如果做到的呢?我们继续 ? ? ? 看下IL代码。 ? ? 从IL中上可以看到,其实所谓的调用方,即:AddRange(1,2,3); 它在调用之前已经new了一个arr,并且将1,2,3 加入到arr中去了,然后再调用AddRange数组的,所以可以看出,又是一枚语法糖。 好了,大概就这样了,夜深了,睡觉了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |