- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个接受dynamic
参数的方法,还有一个不同参数的[CallerMemberName]
。只要动态对象也在参数中,就不会填充 [CallerMemberName]
参数。
这是 CallerMemberName
中的错误还是 C# 本身的错误?看下面的测试
static void Main(string[] args)
{
new CMNTest().BaseMethod();
}
public void BaseMethod()
{
NormalMethod();
dynamic myDyn = new Object();
DynamicArgumentMethod(myDyn);
ObjectArgumentMethod(new object());
ObjectArgumentMethod((object)myDyn);
}
public void NormalMethod([CallerMemberName]string methodName = null)
{
Console.WriteLine(methodName);
}
public void DynamicArgumentMethod(dynamic dynObject, [CallerMemberName]string methodName = null)
{
Console.WriteLine(methodName);
}
public void ObjectArgumentMethod(object otherArg, [CallerMemberName]string methodName = null)
{
Console.WriteLine(methodName);
}
输出:
BaseMethod
<null>
BaseMethod
BaseMethod
在 Visual Studio 和 LinqPad 中测试,结果相同。有办法解决这个问题吗?我需要对对象执行动态
操作,因此无法转换为对象
。
最佳答案
Is this a bug in the CallerMemberName or in C# itself?
没有;存在错误的假设就是错误。
C# CallerMemberName not working with dynamic in args?
没错。这是设计使然。这不是错误。
How does CallerMemberName work?
CallerMemberName 使用与可选参数相同的机制工作;如果您不了解这些机制,那么第一步就是了解它们。请参阅我关于该主题的文章:
http://ericlippert.com/tag/optional-arguments/
在继续之前阅读这些内容。
.....
好的,既然您已经了解可选参数是常量,由编译器在调用点插入,那么现在应该更容易理解调用者如何属性工作。它们是可选参数,替换为调用站点位置的“常量”。
现在想想“动态”是如何工作的。 “动态”意味着“在编译时放弃分析并在运行时重新启动编译器;确定编译器会做什么如果它在编译时知道运行时类型,并像编译器一样生成新代码会产生”。 编译器如何知道将当前位置作为常量保存到调用站点中?它需要这样做的事实是通过编译时重载解析发现的,您刚刚关闭了它.
在运行时运行的编译器没有关于源代码中原始调用位置的信息;该信息不会持久保存到调用站点中,因为原始编译时编译器没有理由相信它需要这样做。
顺便说一句,这与扩展方法无法动态分派(dispatch)的原因相同:调用站点有效负载不包括调用时“在范围内”的所有静态类。
不幸的是,这只是您为全动态调度付出的代价之一。
关于C# CallerMemberName 不能在 args 中使用动态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24939677/
我有这个代码。为了让它工作,我必须使用 Args&&... 而不是 Args... 或 Args&... 我注意到 args 从 & 转换为 const& 或 && 转换为 &。 Args...Arg
当我定义类时,我总是去 Class A(object): def __init__(self, arg): self.arg = arg def print_arg(s
假设我想定义两个 {Type} 类的变量。构造函数采用 1 个参数。下面两种方式是否完全等价(编译成相同的目标代码)? Type a(arg), b(arg); 和 Type a(arg); Type
(旁白:我是一名 Perl 程序员,正如您所知,这是我的第一个重要的 Java 程序。简单的术语将不胜感激。) 我有以下启动器作为编码工作: import java.lang.reflect.*; i
Math.nextUp(arg) 始终与 arg + Math.ulp(arg) 相同,还是我遗漏了什么? System.out.println( 0.5 + Math.ulp(0.5));
今天我在学习完美转发,我创建了这个代码示例 #include #include template auto toStdFun(Function&& fun, Args&&...ar
我想知道你会选择哪个选项? putStrLn (show randomNum) putStrLn $ show randomNum (putStrLn . show) randomNum 所有选项在语
我试图在 visual studio 2012 中编译一个库,它最初是用 c++ 为 visual studio 2015 编写的。我有一个错误说 'class' missing tag。 错误消息的
我在下面的代码中遇到了运行时异常ArrayIndexOutOfBoundException,行中: if ( args[0].equals("t") || args[0].equals("time")
我有以下代码 import React, { Component } from "react"; import { Accounts } from "meteor/accounts-base"; ex
这个问题已经有答案了: Difference between Arrays and 3 dots (Varargs) in java (3 个回答) 已关闭 5 年前。 受学校线性代数 I 和 II
所以我定义了一个函数: def getDistnace(self, strings, parentD, nodeName, nodeDistance): 我用它来调用: Node.getDistnac
这个问题在这里已经有了答案: subprocess.call() arguments ignored when using shell=True w/ list [duplicate] (2 个答案
我想将参数传递给 java 应用程序,但喜欢 linux 应用程序风格。 java 中的main 方法对所有参数使用一个String 数组。在 Linux 中,大多数应用程序接受如下参数:ls -l
这是我的代码片段 #include void change(int a[]){ printf("%p\n",&a); } int main(){
我需要使用 python 3.6 subprocess.run() 函数发出以下命令: gsettings set org.gnome.shell enabled-extensions "['appl
这两个函数是否有任何有意义的不同?有什么理由通常更喜欢一个而不是另一个吗? void foo(auto x, auto &... y) { /* ... */ } template void foo(
例如: def m(arg, ...args) { println "arg: $arg" println "args: $args" } m('arg', k:'v') 输出: ar
我对 Java 还很陌生。目前正在尝试将 args[] 中给出的文件名传递给此 FileReader,但当我编译时,它说找不到指定的文件。如果我对文件名进行硬编码,它就可以正常工作。这应该如何运作?
为什么这是一个语法错误??做这件事的合适方法是什么? >>> def f(*args, option=None): File "", line 1 def f(*args, option=
我是一名优秀的程序员,十分优秀!