方法参数的 c# 自定义属性 - 它是如何工作的?
c# custom attribute for a method parameter - how it works?
我想了解这个特殊案例的工作原理。这是来自 msdn 文章的截图,其中解释了 INotifyPropertyChanged 接口 (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)
正如在标记行中所说的那样,有一种方法可以拦截方法调用来替换一个值而不是实际的参数吗?
我想了解执行此操作的代码是什么样的。我知道如何使用为属性和其他 class 成员设置的属性,但我不清楚这个用例。
谢谢。
这似乎是在编译器中实现的一个功能:它知道这个特殊属性并且它在具有默认值时将调用者的名称替换为可选参数.
如果需要,可以检查 Roslyn 实现。虽然导航并不总是很直接,但在 GetDefaultParameterValue
函数中似乎有一些东西 here (从第 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))
...
最终用于绑定参数:
BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String));
defaultValue = MakeConversion(memberNameLiteral, parameterType, false);
我想了解这个特殊案例的工作原理。这是来自 msdn 文章的截图,其中解释了 INotifyPropertyChanged 接口 (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)
正如在标记行中所说的那样,有一种方法可以拦截方法调用来替换一个值而不是实际的参数吗? 我想了解执行此操作的代码是什么样的。我知道如何使用为属性和其他 class 成员设置的属性,但我不清楚这个用例。
谢谢。
这似乎是在编译器中实现的一个功能:它知道这个特殊属性并且它在具有默认值时将调用者的名称替换为可选参数.
如果需要,可以检查 Roslyn 实现。虽然导航并不总是很直接,但在 GetDefaultParameterValue
函数中似乎有一些东西 here (从第 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))
...
最终用于绑定参数:
BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String));
defaultValue = MakeConversion(memberNameLiteral, parameterType, false);