gpt4 book ai didi

C# CallerMemberName 不能在 args 中使用动态?

转载 作者:太空狗 更新时间:2023-10-30 00:02:52 25 4
gpt4 key购买 nike

我有一个接受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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com