你说得对,欢迎来到properties的精彩世界。
DateTime.Today 是一个属性,简而言之是编译器生成的函数,它转换为DateTime.get_today()。
所以这个表达式实际上是
if ( (DateTime.get_today()).DayOfWeek == DayOfWeek.Monday )
例子:
public class Test
{
private string _lastName = "LName";
private string _firstName = "FName";
public string Name { get{
return _lastName + " " + _firstName;
} }
public string GetName()
{
return _lastName + " " + _firstName;
}
}
class Program
{
static void Main(string[] args)
{
var test = new Test();
Console.WriteLine(test.Name);
Console.WriteLine(DateTime.Today.DayOfWeek);
}
}
反编译GetName
.method public hidebysig instance string
GetName() cil managed
{
// Code size 28 (0x1c)
.maxstack 3
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string ConsoleApplication1.Test::_lastName
IL_0007: ldstr " "
IL_000c: ldarg.0
IL_000d: ldfld string ConsoleApplication1.Test::_firstName
IL_0012: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_0017: stloc.0
IL_0018: br.s IL_001a
IL_001a: ldloc.0
IL_001b: ret
} // end of method Test::GetName
反编译Name
.method public hidebysig specialname instance string
get_Name() cil managed
{
// Code size 28 (0x1c)
.maxstack 3
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string ConsoleApplication1.Test::_lastName
IL_0007: ldstr " "
IL_000c: ldarg.0
IL_000d: ldfld string ConsoleApplication1.Test::_firstName
IL_0012: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_0017: stloc.0
IL_0018: br.s IL_001a
IL_001a: ldloc.0
IL_001b: ret
} // end of method Test::get_Name
反编译Main(方法调用)
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 56 (0x38)
.maxstack 1
.locals init ([0] class ConsoleApplication1.Test test,
[1] valuetype [mscorlib]System.DateTime CS$0$0000)
IL_0000: nop
IL_0001: newobj instance void ConsoleApplication1.Test::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance string ConsoleApplication1.Test::get_Name() //here
IL_000d: call void [mscorlib]System.Console::WriteLine(string)
IL_0012: nop
IL_0013: ldloc.0
IL_0014: callvirt instance string ConsoleApplication1.Test::GetName()//here
IL_0019: call void [mscorlib]System.Console::WriteLine(string)
IL_001e: nop
IL_001f: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Today()//here
IL_0024: stloc.1
IL_0025: ldloca.s CS$0$0000
IL_0027: call instance valuetype [mscorlib]System.DayOfWeek [mscorlib]System.DateTime::get_DayOfWeek()
IL_002c: box [mscorlib]System.DayOfWeek
IL_0031: call void [mscorlib]System.Console::WriteLine(object)
IL_0036: nop
IL_0037: ret
} // end of method Program::Main
如您所见,Name 和 GetName 之间绝对没有区别,除了 Name 是由编译器为您生成的 get_Name。
更新 1
至于DateTime.Today,它实际上变成了
System.DateTime [mscorlib]System.DateTime::get_Today()
您必须了解的是,即使编译器为您生成了这些函数,也无法直接访问它们,因为它生成的是 IL 代码(.NET 的汇编代码)而不是 C#(随着 Roslyn C# 编译器,但不太了解)
如果您真的对应用程序中真正发生的事情感到好奇,我建议您使用ildasm.exe,它可以让您查看编译器生成的 IL。一本很好的书,它通过 C# 调用 CLR,我接触过第 3 版,但显然现在有第 4 版了。