[英]C# Why i can call object extension methods on constants?
在C#中為什么我可以打電話
var intStr = 1.ToString();
var strStr = "1".ToString();
1和“1”是常量文字所以為什么object.ToString()
不會導致錯誤?
為什么我可以在常量上調用對象擴展方法?
那些不是擴展方法。
1
和"1"
是常量,為什么ToString()
不會導致錯誤?
你的問題在沒有解釋為什么你認為這首先應該成為一個問題的問題時會問“為什么不”。 在將來詢問此表格的問題時,請說明為什么您認為該行動應該被禁止。
所以讓我們試着讀懂你的想法。 這是你可能會問的一個問題:
1
和"1"
是文字,但點的左側必須是符號 ,如x
,那么為什么1.ToString()
不會導致錯誤?
假設不正確。 成員訪問點左側的東西必須是表達式。 這種表達有限制; 例如,它不能是返回void的方法調用。 但它沒有限制它是文字。
這是你可能會問的另一個問題:
1
是值類型的常量,但值類型的方法的接收者必須是變量,因為方法中的this
是對變量的ref
。 那么為什么1.ToString()
不會導致錯誤呢?
如果方法調用的所述接收器是一個值的類型,並且this
必須的ref
類型,但是接收機表達不被分類為一個變量則編譯器拷貝的值到一個臨時變量,並傳遞一個ref
給該變量。
這意味着如果方法改變變量,則突變會丟失,因為它是在副本上執行的。 這是可變值類型是一種不好的做法的另一個原因。 不小心丟失突變很容易!
這是你可能會問的另一個問題:
1.
是浮點數,雙精度或十進制數字的開頭; 接下來的事情應該是一個數字。 那么為什么1.ToString()
不會導致錯誤呢?
這個問題做出了錯誤的假設。 詞法分析器檢查點后面的東西是否是數字; 如果它然后它保持lexing文字作為浮點數,雙精度或小數。 (它將由后綴確定,如果有的話。)如果點后面的東西不是數字,則詞法分析器將點作為成員訪問點,並開始為ToString
新的令牌。
它們是從常量文字(在程序文本中)初始化的,但它們實際上是對象(因為它們在邏輯上被視為對象),並且所有對象都實現了ToString()
所以1
是System.Int32
類型。
因此,您可以為它們調用ToString()
。
為此生成的IL是這樣的:
L_0001: ldc.i4.1
L_0002: stloc.1
L_0003: ldloca.s CS$0$0000
L_0005: call instance string [mscorlib]System.Int32::ToString()
請注意, ldc.i4.1
是一個特殊指令,它將值為1的System.Int32
入堆棧。 具體而言,這是實際“創建” System.Int32
值對象的指令。
另請注意,盡管System.Int32是值類型,但它也被視為對象,因此以下語句始終為true:
bool isObject = (1 is object);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.