CallerMemberName 如何从内部工作?
How does CallerMemberName work from inside?
我找不到任何文档或至少无法从内部找到此类属性如何工作的解释。
[CallerMemberName]
[CallerFilePath]
[CallerLineNumber]
Documentation I found 仅显示如何使用它。
是否可以创建您自己的 [CallerMemberNameAttribute] 实现或一些自定义 [CallerObjectAttribute]?
这对我来说很有趣,只是为了学习目的和理解背后的代码。
所以仅供学习之用。属性本身对方法本身没有任何作用,但对它的调用方式有影响。
如果编译器必须创建对该方法的调用,他会检查每个参数,如果它具有这些属性之一,如果是,它会将调用者的名称或文件作为参数值传递。它用另一个默认值覆盖默认值。将默认参数放在那里的要求只是让编译器允许您首先省略此参数。
假设您有这样的代码:
static void Main(string[] args)
{
Test();
Test1();
}
public static void Test(string name = "")
{
Console.WriteLine(name);
}
public static void Test1([CallerMemberName] string name = "")
{
Console.WriteLine(name);
}
生成的代码与
相同
static void Main(string[] args)
{
Test("");
Test1("Main");
}
除非您修改编译器本身,否则您无法通过您的编程模拟这一点。如果调用者的编译器找到这个属性,就会放入这个“Main”字符串(或当前编译的文件的名称)。
如果您显式传递参数值,如代码示例的最后一行,默认值和 CallerMemberName 属性都将被忽略。
我找不到任何文档或至少无法从内部找到此类属性如何工作的解释。
[CallerMemberName]
[CallerFilePath]
[CallerLineNumber]
Documentation I found 仅显示如何使用它。
是否可以创建您自己的 [CallerMemberNameAttribute] 实现或一些自定义 [CallerObjectAttribute]?
这对我来说很有趣,只是为了学习目的和理解背后的代码。
所以仅供学习之用。属性本身对方法本身没有任何作用,但对它的调用方式有影响。
如果编译器必须创建对该方法的调用,他会检查每个参数,如果它具有这些属性之一,如果是,它会将调用者的名称或文件作为参数值传递。它用另一个默认值覆盖默认值。将默认参数放在那里的要求只是让编译器允许您首先省略此参数。
假设您有这样的代码:
static void Main(string[] args)
{
Test();
Test1();
}
public static void Test(string name = "")
{
Console.WriteLine(name);
}
public static void Test1([CallerMemberName] string name = "")
{
Console.WriteLine(name);
}
生成的代码与
相同 static void Main(string[] args)
{
Test("");
Test1("Main");
}
除非您修改编译器本身,否则您无法通过您的编程模拟这一点。如果调用者的编译器找到这个属性,就会放入这个“Main”字符串(或当前编译的文件的名称)。
如果您显式传递参数值,如代码示例的最后一行,默认值和 CallerMemberName 属性都将被忽略。