如果我编写以下代码,ReSharper会建议我将第一个变量chr3
转换为常量,而不是第二个变量chr127
。
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)
?
答案 0 :(得分:1)
字符3是“文本结束”字符,因此它可能表现出奇怪的行为似乎并不令人惊讶。这个和其他类似的字符很少直接使用。
答案 1 :(得分: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"/> < 0 or > 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位值,当前文化&# 39; s 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()
与调用它的代码存在于同一个程序集中,所以这可能无论如何都没有用。)