- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
以下两个 C#
函数的不同之处仅在于将参数的左/右顺序交换为 equals 运算符 ==
。 (IsInitialized
的类型是bool
)。使用 C# 7.1 和 .NET 4.7。
static void A(ISupportInitialize x)
{
if ((x as ISupportInitializeNotification)?.IsInitialized == true)
throw null;
}
static void B(ISupportInitialize x)
{
if (true == (x as ISupportInitializeNotification)?.IsInitialized)
throw null;
}
但是第二个的IL 代码 似乎要复杂得多。例如,B 是:
newobj
和 initobj
;[0] bool flag
nop
ldarg.0
isinst [System]ISupportInitializeNotification
dup
brtrue.s L_000e
pop
ldc.i4.0
br.s L_0013
L_000e: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
L_0013: stloc.0
ldloc.0
brfalse.s L_0019
ldnull
throw
L_0019: ret
[0] bool flag,
[1] bool flag2,
[2] valuetype [mscorlib]Nullable`1<bool> nullable,
[3] valuetype [mscorlib]Nullable`1<bool> nullable2
nop
ldc.i4.1
stloc.1
ldarg.0
isinst [System]ISupportInitializeNotification
dup
brtrue.s L_0018
pop
ldloca.s nullable2
initobj [mscorlib]Nullable`1<bool>
ldloc.3
br.s L_0022
L_0018: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
newobj instance void [mscorlib]Nullable`1<bool>::.ctor(!0)
L_0022: stloc.2
ldloc.1
ldloca.s nullable
call instance !0 [mscorlib]Nullable`1<bool>::GetValueOrDefault()
beq.s L_0030
ldc.i4.0
br.s L_0037
L_0030: ldloca.s nullable
call instance bool [mscorlib]Nullable`1<bool>::get_HasValue()
L_0037: stloc.0
ldloc.0
brfalse.s L_003d
ldnull
throw
L_003d: ret
==
的左侧 之间的差异来解释,(这里是属性引用表达式与文字值),可以您指定了描述详细信息的 C# 规范部分。 奖金。每个堆栈的最终 JITted x86
或 AMD64
代码如何叠加?
根据评论中的反馈添加的附加说明。首先,提出了第三个变体,但它提供与 A 相同的 IL(对于 Debug
和 Release
构建)。然而,从语法上看,新版本的 C# 确实比 A 更时尚:
static void C(ISupportInitialize x)
{
if ((x as ISupportInitializeNotification)?.IsInitialized ?? false)
throw null;
}
这里还有每个函数的 Release
IL。请注意,A/C 与 B 的不对称性在 Release
IL 中仍然很明显,因此原始问题依然屹立不倒。
ldarg.0
isinst [System]ISupportInitializeNotification
dup
brtrue.s L_000d
pop
ldc.i4.0
br.s L_0012
L_000d: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
brfalse.s L_0016
ldnull
throw
L_0016: ret
[0] valuetype [mscorlib]Nullable`1<bool> nullable,
[1] valuetype [mscorlib]Nullable`1<bool> nullable2
ldc.i4.1
ldarg.0
isinst [System]ISupportInitializeNotification
dup
brtrue.s L_0016
pop
ldloca.s nullable2
initobj [mscorlib]Nullable`1<bool>
ldloc.1
br.s L_0020
L_0016: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
newobj instance void [mscorlib]Nullable`1<bool>::.ctor(!0)
L_0020: stloc.0
ldloca.s nullable
call instance !0 [mscorlib]Nullable`1<bool>::GetValueOrDefault()
beq.s L_002d
ldc.i4.0
br.s L_0034
L_002d: ldloca.s nullable
call instance bool [mscorlib]Nullable`1<bool>::get_HasValue()
L_0034: brfalse.s L_0038
ldnull
throw
L_0038: ret
最后,提到了一个使用新的 C# 7 语法的版本,它似乎产生了所有 IL 中最干净的:
static void D(ISupportInitialize x)
{
if (x is ISupportInitializeNotification y && y.IsInitialized)
throw null;
}
[0] class [System]ISupportInitializeNotification y
ldarg.0
isinst [System]ISupportInitializeNotification
dup
stloc.0
brfalse.s L_0014
ldloc.0
callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
brfalse.s L_0014
ldnull
throw
L_0014: ret
最佳答案
所以我对答案很好奇并查看了 c# 6 规范(不知道托管 c# 7 规范的位置)。完全免责声明:我不保证我的回答是正确的,因为我没有编写 c# 规范/编译器并且我对内部的理解是有限的。
但我认为答案在于 overloadable 的结果==
运算符(operator)。 ==
的最佳适用过载通过使用 better function members 的规则确定.
来自规范:
Given an argument list A with a set of argument expressions {E1, E2, ..., En} and two applicable function members Mp and Mq with parameter types {P1, P2, ..., Pn} and {Q1, Q2, ..., Qn}, Mp is defined to be a better function member than Mq if
for each argument, the implicit conversion from Ex to Qx is not better than the implicit conversion from Ex to Px, and for at least one argument, the conversion from Ex to Px is better than the conversion from Ex to Qx.
引起我注意的是参数列表 {E1, E2, .., En}
.如果你比较 Nullable<bool>
到 bool
参数列表应该类似于 {Nullable<bool> a, bool b}
并为该参数列出 Nullable<bool>.Equals(object o)
方法似乎是最好的函数,因为它只需要从 bool
进行一次隐式转换。至 object
.
但是,如果您将参数列表的顺序恢复为 {bool a, Nullable<bool> b}
Nullable<bool>.Equals(object o)
方法不再是最好的功能,因为现在你必须从 Nullable<bool>
转换至 bool
在第一个参数中,然后来自 bool
至 object
在第二个参数中。这就是为什么对于案例 A 选择了不同的重载,这似乎导致了更清晰的 IL 代码。
同样,这是满足我自己好奇心的解释,似乎符合 c# 规范。但我还没有弄清楚如何调试编译器以查看实际发生的情况。
关于c# - 带有 Nullable<T> 的 '==' 的参数顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45751945/
我想使用 li 和 ul 制作一个多级下拉列表,以便显示我博客中按年和月排序的所有文章。我希望我的下拉菜单看起来像 Google Blogspot 下拉菜单: 这是我的 CSS 和 HTML 代码 u
我在 Win 7 64 机器上将 CodeBlocks 与 gcc 4.7.2 和 gmp 5.0.5 结合使用。开始使用 gmpxx 后,我看到一个奇怪的段错误,它不会出现在 +、- 等运算符中,但
我正在使用 tern 为使用 CodeMirror 运行的窗口提供一些增强的智能感知,它工作正常,但我遇到了一个问题,我想添加一些自定义“types”,可以这么说,这样下拉列表中它们旁边就有图标了。我
我正在尝试让我的 PC 成为 Android 2.3.4 设备的 USB 主机,以便能够在不需要实际“附件”的情况下开发 API。为此,我需要将 PC 设置为 USB 主机和“设备”(在我的例子中是运
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我在设置服务器方面几乎是个新手,但遇到了一个问题。我有一个 Ubuntu 16.04 VPS 并安装了 Apache2 和 Tomcat7。我正在为 SSL 使用 LetsEncrypt 和 Cert
我在一个基于谷歌地图的项目上工作了超过 6 个月。我使用的是 Google Maps API V1 及其开发人员 API key 。当我尝试发布应用程序时,我了解到 Google API V1 已被弃
我是 Python 的新手,所以如果我对一些简单的事情感到困惑,请原谅。 我有一个这样的对象: class myObject(object): def __init__(self):
这个问题已经有答案了: How can I access object properties containing special characters? (2 个回答) 已关闭 9 年前。 我正在尝
我有下面的 CSS。我想要的是一种流体/液体(因为缺乏正确的术语)css。我正在为移动设备开发,当我改变模式时 从纵向 View 到陆地 View ,我希望它流畅。现在的图像 在陆地 View 中效
我正在尝试使用可以接受参数的缓存属性装饰器。 我查看了这个实现:http://www.daniweb.com/software-development/python/code/217241/a-cac
这个问题在这里已经有了答案: Understanding slicing (36 个答案) 关闭 6 年前。 以a = [1,2,3,4,5]为例。根据我的直觉,我认为 a[::-1] 与 a[0:
mysqldump -t -u root -p mytestdb mytable --where=datetime LIKE '2014-09%' 这就是我正在做的事情,它会返回: mysqldum
我正在制作销售税计算器,除了总支付金额部分外,其他一切都正常。在我的程序中,我希望能够输入一个数字并获得该项目的税额我还希望能够获得支付的总金额,包括交易中的税金。到目前为止,我编写的代码完成了所有这
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
我是否必须进行任何额外的设置才能让 apache-airflow 在任务失败时向我发送电子邮件。我的配置文件中有以下内容(与默认值保持不变): [email] email_backend = airf
这个问题在这里已经有了答案: What does the $ symbol do in VBA? (5 个回答) 3年前关闭。 使用返回字符串(如 Left)的内置函数有什么区别吗?或使用与 $ 相同
我有一个用VB6编写的应用程序,我需要使用一个用.NET编写的库。有什么方法可以在我的应用程序上使用该库吗? 谢谢 最佳答案 这取决于。您可以控制.NET库吗? 如果是这样,则可以修改您的库,以便可以
当我创建一个以 ^ 开头的类方法时,我尝试调用它,它给了我一个错误。 class C { method ^test () { "Hi" } } dd C.new.test; Too m
我已经使用 bower 安装了 angularjs 和 materialjs。 凉亭安装 Angular Material 并将“ngMaterial”注入(inject)我的应用程序,但出现此错误。
我是一名优秀的程序员,十分优秀!