2019-5-21-C#-在-构造函数添加-CallerMemberName-会怎样
title | author | date | CreateTime | categories |
---|---|---|---|---|
C# 在 构造函数添加 CallerMemberName 会怎样
|
lindexi
|
2019-05-21 11:28:32 +0800
|
2019-1-2 19:6:44 +0800
|
C#
|
在 C# 中有一个特性 CallerMemberName 可以给方法知道调用这个方法的方法名,在 UWP 中用这个特性很多,特别是在使用 MVVM 绑定
如果在构造函数使用这个特性会发生什么?
构造函数可能是方法调用,可能是反射调用,可能是基类使用,这些使用的值是什么?
先定义一个类
public class F1
{
/// <inheritdoc />
public F1([CallerMemberName] string name = "")
{
Debug.WriteLine(name);
}
}
小伙伴都知道,下面的代码会输出 Foo 因为在这个方法调用
public MainWindow()
{
InitializeComponent(); Foo();
} private void Foo()
{
new F1();
}
在方法调用的时候,小伙伴都知道 CallerMemberName 能拿到调用的方法,在 .NET 4.5 之后提供的这个特性实在好用,通过这个特性就可以在参数传入调用的方法,同时因为这个特性是在编译时添加的,所以比反射快很多。
但是如果再添加一个类 F2 继承 F1 会出现什么?
public MainWindow()
{
InitializeComponent(); new F2();
} public class F2 : F1
{
/// <inheritdoc />
public F2()
{
}
}
现在运行代码,发现这个值居然是空
但是如果此时修改 F2 函数,这时输出的就是 .ctor
因为 CallerMemberName 是编译做的
public class F2 : F1
{
/// <inheritdoc />
public F2() : base()
{
}
}
分析一下两个的 IL 代码就知道,在 public F2() : base()
的 IL 代码
.method public hidebysig specialname rtspecialname instance void
.ctor() cil managed
{
.maxstack 8
// [50 23 - 50 29]
IL_0000: ldarg.0 // this
IL_0001: ldstr ".ctor" // 压入字符串 .ctor 然后调用 F1 的构造函数
IL_0006: call instance void lindexi.F1::.ctor(string)
// 在这个构造函数传入刚才压的字符串,也就是 F1(".ctor") 在 F1 的 name 就是这里传入的字符串
IL_000b: nop
// [51 9 - 51 10]
IL_000c: nop
// [52 9 - 52 10]
IL_000d: ret
}
在 public F2()
的 IL 代码其实几乎没有多少修改
.method public hidebysig specialname rtspecialname instance void
.ctor() cil managed
{
.maxstack 8 // [50 9 - 50 20]
IL_0000: ldarg.0 // this
IL_0001: ldstr "" // 只有这句和上面不同,传入的是空所以在 F1 收到的值就是这里传入
IL_0006: call instance void lindexi.F1::.ctor(string)
IL_000b: nop // [51 9 - 51 10]
IL_000c: nop // [52 9 - 52 10]
IL_000d: ret }
可以看到虽然调用的方法看起来是相同的,但是运行的结果是不相同的,因为 CallerMemberName 是在编译时做的
从上面的 IL 也可以看到 CallerMemberName 是在编译的时候传入的值,性能会比反射快,如果需要获得调用这个方法的方法的方法,也就是 A 调 B 然后 B 调 C 需要在 C 里面知道 A 是哪个,就需要使用 WPF 判断调用方法堆栈
2019-5-21-C#-在-构造函数添加-CallerMemberName-会怎样的更多相关文章
- C# 在 构造函数添加 CallerMemberName 会怎样
在 C# 中有一个特性 CallerMemberName 可以给方法知道调用这个方法的方法名,在 UWP 中用这个特性很多,特别是在使用 MVVM 绑定 如果在构造函数使用这个特性会发生什么? 构造函 ...
- 2019.3.18考试&2019.3.19考试&2019.3.21考试
2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...
- 2019.04.21 python核心特征
本阶段我们将了解Python是如何管理内存的,学习内存管理让我们掌握python的运行机制: 并且在python中有许多函数式编程的特性,比如闭包,装饰器和生成器,这些都是一些比较难掌握的概念,但面试 ...
- 2019.03.21 admin
1.新建文件创建一个应用类 stu Python manage.py startapp stu 2,创建应用类 记得在setting中的installed_apps中添加应用 student/mode ...
- 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)
传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...
- 给Date的构造函数添加属性和方法
let d = Date.prototype; Object.defineProperties(d, { 'year': { get: function () { return this.getFul ...
- 2019.10.21 csp-s模拟测试81 反思总结
T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法 ...
- 2019.2.21 T2题解
meet 大概思路就是 , 找出相交的路径 , 判断方向 , 分类讨论.. 假设已经找出了相交路径 ... 若方向相同 , 则找到相交路径上边权的最大值 , 若最大值>出发时间差 , 则可行. ...
- Vue集成tinymce富文本编辑器并实现本地化指南(2019.11.21最新)
tinymce是一款综合口碑特别好.功能异常强大的富文本编辑器,在某些网站,甚至享有"宇宙最强富文本编辑器"的称号.那么,在Vue项目中如何集成呢?这并不困难,只需要参照官方教程 ...
随机推荐
- 解析Mybatis入门第三天
目的:使用mybatis对数据的一些标签的使用和表与表之间的一对多和多对一的查询方式. 例如:if.where.foreach 前言:同样是使用idea创建一个普通的maven工程(如何创建一个普通的 ...
- hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability
题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...
- python非对称加密模块rsa
一.代码 # 导入rsa库 import rsa.common class RSA(object): def __init__(self): self.key= rsa.newkeys(256) se ...
- csp-s模拟测试86
csp-s模拟测试86 分屋前的最后一次考试,我早就放弃了自己. 02:02:46 70 02:02:57 03:16:08 100 03:16:08 $T1$忘了按位计算,达哥按位计算的$T1$当时 ...
- 杂项-Maven-guava:guava
ylbtech-杂项-Maven-guava:guava Guava是一种基于开源的Java库,其中包含谷歌正在由他们很多项目使用的很多核心库.这个库是为了方便编码,并减少编码错误.这个库提供用于集合 ...
- windows sdk版本 之 并查集生成迷宫
#include <cstdlib> #include <ctime> #include<algorithm> using namespace std; exter ...
- “瑞士军刀”Netcat使用方法总结
前言 最近在做渗透测试的时候遇到了端口监听和shell的反弹问题,在这个过程中自己对Netcat这一款神器有了新的认识,现将一些Netcat的用法做一个小总结,希望对各位有帮助! Netcat简介 N ...
- 深入分析Service启动、绑定过程
Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作.Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行.Service 是 ...
- 通过aapt查看apk包名和第一个启动的activity
步骤: ps:aapt是sdk 自带的一个工具,在sdk\builds-tools目录下: 1. cmd启动控制台, 默认是c盘,输入“d:” 即可转到D盘目录 2. 到D盘后 输入cd 子文件目录转 ...
- vue通过修改element-ui相关类的样式修改element-ui组件的样式
可以在App.vue中的style中修改element-ui的样式. .el-menu{ width:160px !important; } 注意:一定要在属性值后面加上 !important 使自己 ...