4

如果我编写以下代码,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

如果我将两者都转换为常量,我会收到一个 Visual Studio 编译器警告,Chr(172)说明“需要常量表达式”,但没有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)

4

2 回答 2

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()与调用它的代码存在于同一个程序集中,所以这可能无论如何都不起作用。)

于 2013-06-05T00:01:36.220 回答
1

字符 3 是“文本结尾”字符,因此它可能表现出奇怪的行为似乎不足为奇。这个和其他类似的字符很少直接使用。

于 2013-06-04T23:34:26.470 回答