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项目中如何集成呢?这并不困难,只需要参照官方教程 ...
 
随机推荐
- 使用FastJson转化Json格式
			
1.下载Jar包 http://repo1.maven.org/maven2/com/alibaba/fastjson/ 2.将jar包导入工程 3.示例 package nc.testFastJso ...
 - 06.Mybatis关联查询
			
1.一对一关联查询 需求:查询出每条orders记录和其关联的user信息 在orders实体类中添加属性与set.get方法 /** * 测试1对1关联查询 */ private User user ...
 - vue 项目 去哪儿
			
去哪儿项目 使用vue +vue-router+vuex +axios完成,包括3个部分内容 1.首页演示,包括首页header,首页轮播图,周末去哪儿,热销推荐开发 2.城市列表页面开发 ,包括城市 ...
 - css---6伪元素选择器
			
after :在内容后边 <!DOCTYPE html> <html lang="en"> <head> & ...
 - 选择器zuoye
			
代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title ...
 - GCRoots 对象
			
GC Roots 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中的类静态属性引用的对象 方法区中的常量引用的对象 原生方法栈(Native Method Stack)中 JNI 中引用的对象 可 ...
 - Bzoj 1036 树的统计                                                    分类:            ACM TYPE             2014-12-29 18:55    72人阅读    评论(0)    收藏
			
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
 - python常用包及功能介绍
			
1.NumPy数值计算 NumPy是使用Python进行科学计算的基础包,Numpy可以提供数组支持以及相应的高效处理函数,是Python数据分析的基础,也是SciPy.Pandas等数据处理和科学计 ...
 - java_JDK8中新增的时间API
			
java.time 包含值对象的基础包 java.time.chrono 提供对不同的日历系统的访问 java.time.format 格式化和解析时间的日期 java.time.temporal 包 ...
 - crontab中反引号和$()无效的解决
			
问题描述 1.增加了一条crontab,删除本月中2天以前的日志 10 02 * * * /bin/find /data/logs/php/$(date +%Y%m)/ -mtime +2 | x ...