我想了解这个特殊案例的工作原理。这是来自 msdn 文章的截图,其中解释了 INotifyPropertyChanged 接口(interface)(https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k%28System.ComponentModel.INotifyPropertyChanged%29;k%28TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5%29;k%28DevLang-csharp%29&rd=true)
正如在标记行中所说的那样,有一种方法可以拦截方法调用来替换一个值而不是实际的参数吗? 我想了解执行此操作的代码是什么样的。我知道如何使用为属性和其他类成员设置的属性,但我不清楚这个用例。
谢谢。
最佳答案
这似乎是编译器中实现的一项功能:它知道这个特殊属性,并且它在具有默认值时将调用者的名称替换为可选参数。
如果需要,您可以检查 Roslyn 实现。虽然导航并不总是很简单,但似乎有一些东西 here在GetDefaultParameterValue
函数(从第 844 行开始,至少在撰写本文时的当前版本中是这样 -- 0db946b
):
if the optional parameter is annotated with
<see cref="CallerLineNumberAttribute"/>
,<see cref="CallerFilePathAttribute"/>
or<see cref="CallerMemberNameAttribute"/>
, and there is no explicit argument corresponding to it, we will provide caller information as a value of this parameter.
在第 912 行有一个 else if
处理这种情况的子句(之前的 if
和 else if
子句处理类似的新功能 CallerLineNumberAttribute
和 CallerFilePathAttribute
):
...
else if (parameter.IsCallerMemberName && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
...
最终用于绑定(bind)参数:
BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String));
defaultValue = MakeConversion(memberNameLiteral, parameterType, false);
关于方法参数的 c# 自定义属性 - 它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33827622/