2013-06-04 44 views
4

如果我編寫以下代碼,ReSharper會建議我將第一個變量chr3轉換爲常量,而不是第二個變量chr127爲什麼Chr(3)是一個常量表達式,但不是Chr(172)?

Public Class ClassX 
    Public Sub SomeMethod() 
     Dim chr3 As String = Chr(3) 
     Dim chr172 As String = Chr(172) 

     Debug.WriteLine(chr3) 
     Debug.WriteLine(chr172) 
    End Sub 
End Class 

如果我都轉換爲常量,我上Chr(172)一個Visual Studio編譯器警告,指出了「常量表達式需要」,但沒有編譯器警告的Chr(3)

Public Class ClassX 
    Public Sub SomeMethod() 
     Const chr3 As String = Chr(3) 
     Const chr172 As String = Chr(172) 

     Debug.WriteLine(chr3) 
     Debug.WriteLine(chr172) 
    End Sub 
End Class 

是什麼讓Chr(3)一個常量表達式,但不Chr(172)

+1

+1有趣的問題。我很確定它與172在標準ASCII表之外有什麼關係(它是7位,我期望你的問題發生在高於127的值),但我不知道爲什麼它會打擾編譯器。 –

+0

良好的洞察力。它似乎與8位值有關,因爲樣本值122和127被接受爲常量表達式,但128和172不是。 – MCattle

+0

+1有趣的問題 – SSS

回答

1

展望的源代碼Microsoft.VisualBasic.Strings.Chr(),我看到以下(我已經簡化了此篇通過除去異常處理):

/// <summary> 
/// Returns the character associated with the specified character code. 
/// </summary> 
/// 
/// <returns> 
/// Returns the character associated with the specified character code. 
/// </returns> 
/// <param name="CharCode">Required. An Integer expression representing the code point, or character code, for the character.</param><exception cref="T:System.ArgumentException"><paramref name="CharCode"/> &lt; 0 or &gt; 255 for Chr.</exception><filterpriority>1</filterpriority> 
public static char Chr(int CharCode) 
{ 
    if (CharCode <= (int) sbyte.MaxValue) 
    return Convert.ToChar(CharCode); 

    Encoding encoding = Encoding.GetEncoding(Utils.GetLocaleCodePage()); 
    char[] chars1 = new char[2]; 
    byte[] bytes = new byte[2]; 
    Decoder decoder = encoding.GetDecoder(); 
    int chars2; 
    if (CharCode >= 0 && CharCode <= (int) byte.MaxValue) 
    { 
    bytes[0] = checked ((byte) (CharCode & (int) byte.MaxValue)); 
    chars2 = decoder.GetChars(bytes, 0, 1, chars1, 0); 
    } 
    else 
    { 
    bytes[0] = checked ((byte) ((CharCode & 65280) >> 8)); 
    bytes[1] = checked ((byte) (CharCode & (int) byte.MaxValue)); 
    chars2 = decoder.GetChars(bytes, 0, 2, chars1, 0); 
    } 
    return chars1[0]; 
} 

這似乎是,對於7位值,Convert.ToChar(CharCode)被返回,我猜測編譯器足夠聰明,可以得出結論是一個常量,而對於8位值的當前文化的CodePage會涉及到,這將給出基於計算機運行代碼的不同結果,因此不能一個常數。

更新:我試圖複製我自己編寫的方法中的情況,但不能,這表明編譯器本身可能有一個用於評估常量表達式的特殊情況規則。

Private Function ConstOrNot(input As Int32) As Int32 
    If input = 3 Then Return 7 
    Return (New Random).Next 
End Function 

Const intC1 As Int32 = ConstOrNot(3) 

(這就是說,ConstOrNot()存在於同一個組件的代碼調用它,所以這可能不會反正工作。)

1

字符3是「文本的結尾」字符,所以似乎並不奇怪它可能會表現出奇怪的行爲。這個和其他類似的字符很少直接使用。

相關問題