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-会怎样的更多相关文章

  1. C# 在 构造函数添加 CallerMemberName 会怎样

    在 C# 中有一个特性 CallerMemberName 可以给方法知道调用这个方法的方法名,在 UWP 中用这个特性很多,特别是在使用 MVVM 绑定 如果在构造函数使用这个特性会发生什么? 构造函 ...

  2. 2019.3.18考试&2019.3.19考试&2019.3.21考试

    2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...

  3. 2019.04.21 python核心特征

    本阶段我们将了解Python是如何管理内存的,学习内存管理让我们掌握python的运行机制: 并且在python中有许多函数式编程的特性,比如闭包,装饰器和生成器,这些都是一些比较难掌握的概念,但面试 ...

  4. 2019.03.21 admin

    1.新建文件创建一个应用类 stu Python manage.py startapp stu 2,创建应用类 记得在setting中的installed_apps中添加应用 student/mode ...

  5. 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)

    传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...

  6. 给Date的构造函数添加属性和方法

    let d = Date.prototype; Object.defineProperties(d, { 'year': { get: function () { return this.getFul ...

  7. 2019.10.21 csp-s模拟测试81 反思总结

    T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法 ...

  8. 2019.2.21 T2题解

    meet 大概思路就是 , 找出相交的路径 , 判断方向 , 分类讨论.. 假设已经找出了相交路径 ... 若方向相同 , 则找到相交路径上边权的最大值 , 若最大值>出发时间差 , 则可行. ...

  9. Vue集成tinymce富文本编辑器并实现本地化指南(2019.11.21最新)

     tinymce是一款综合口碑特别好.功能异常强大的富文本编辑器,在某些网站,甚至享有"宇宙最强富文本编辑器"的称号.那么,在Vue项目中如何集成呢?这并不困难,只需要参照官方教程 ...

随机推荐

  1. Bootstrap 附加导航(Affix)插件

    附加导航(Affix)插件允许指定 <div> 固定在页面的某个位置.一个常见的例子是社交图标.它们将在某个位置开始,但当页面点击某个标记,该 <div> 会锁定在某个位置,不 ...

  2. Django项目基础配置和基本使用

    博文配置内容包括: django项目的创建 django项目下应用的创建及配置 数据库的配置 templates模板的配置 命令行创建项目: 在需要的目录下创建Django项目输入命令:django- ...

  3. leetcode-216-组合总和③

    题目描述: 方法一:回溯 class Solution: def combinationSum3(self, k: int, n: int) -> List[List[int]]: res = ...

  4. Java 基础 - 原生类型

    更详细的说明,请参考: Java 原生类型与包装器类型深度剖析,https://blog.csdn.net/justloveyou_/article/details/52651211 一. 原生类型与 ...

  5. Flask扩展 -- flask-mail

    电子邮件是最常用的通信方式之一.虽然Python标准库中的smtplib包可用在Flask程序中发送电子邮件,但包装了smtplib的Flask-Mail扩展能更好的和Flask集成. 1.安装Fla ...

  6. 概率+后效性处理——cf930B好题

    之前题目看错了.. 先用双倍字符串处理后效性 首先要确定一个结论:如果原串s中相距为d的ch1和ch2只有一对,那么如果第一个翻开ch1,第二个翻开ch2,就能确定k 现在要求的是当我们第一次翻开的是 ...

  7. 跨域问题The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by t

    withCredentials 属性 上面说到,CORS请求默认不发送Cookie和HTTP认证信息.如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow- ...

  8. LUOGU P4042 [AHOI2014/JSOI2014]骑士游戏 (spfa+dp)

    传送门 解题思路 首先设\(f[x]\)表示消灭\(x\)的最小花费,那么转移方程就是 \(f[x]=min(f[x],\sum f[son[x]] +s[x])\),如果这个转移是一个有向无环图,那 ...

  9. 正则表达式 判断内容是否为合法的url

    var strUrl= "^((https|http|ftp|rtsp|mms)?://)" + "?(([0-9a-z_!~*'().&=+$%-]+: )?[ ...

  10. git撤销修改及版本回退

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file. 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步, ...