我刚刚使用 struct DateTime.Today 看到了一些代码段代码,我无法理解它的内部工作原理。这是具体的一行:
if (DateTime.Today.DayOfWeek == DayOfWeek.Monday)
使用转到定义F12 之后,我看到今天静态方法返回 一个DateTime对象,其中包含当前计算机中的日期信息。我想 Today方法可以作为构造函数包装器使用。我无法推断的(更像是猜测)是如何在不首先实例化今日结构的情况下访问属性DayOfWeek 。
有人可以解释一下这怎么可能?我唯一的猜测是,当VS将代码编译为 IL 时,可能会将此语法糖转换为:
if ( (DateTime.Today()).DayOfWeek == DayOfWeek.Monday )
也许这就像水一样干净,但我是C#新手,所以我无法理解。
提前致谢!
答案 0 :(得分:2)
与您的问题相关,DateTime.Today
是Property
类型的DateTime
,因此DateTime.DayOfWeek
Property
与常规DateTime
一样Properties
} 结构体。
广义上讲Properties
如何在C#中工作:在第一次近似中,为了更好地理解,您可能会认为Methods
伪装成Today
看起来像一个字段,因此,您对GetToday()
作为某种假设的Properties
方法的解释在逻辑上是接近的,但在学术上并不精确" (见@CalebB的评论)。
我建议您熟悉.NET DateTime
(https://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx)和Structure
JavaDStream<Status> inputDStream = TwitterUtils.createStream(ctx, new OAuthAuthorization(builder.build()), filters);
inputDStream.foreach(new Function2<JavaRDD<Status>,Time,Void>(){
@Override
public Void call(JavaRDD<Status> status, Time time) throws Exception {
List<Status> statuses=status.collect();
for(Status st:statuses){
System.out.println("STATUS:"+st.getText()+" user:"+st.getUser().getId());
//Process and store status somewhere
}
return null;
}});
ctx.start();
ctx.awaitTermination();
}
(https://msdn.microsoft.com/en-us/libraRy/system.datetime.aspx)
希望这可能会有所帮助。
答案 1 :(得分:1)
你是对的,欢迎来到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版。