1. ホーム
  2. vb.net

[解決済み] Chr(3)は定数式なのに、Chr(172)は定数式でないのはなぜですか?

2022-03-03 03:01:48

疑問点

以下のコードを書くと、ReSharperは最初の変数を変換するよう提案します。 chr3 を定数に変換し、2つ目の変数には変換しない。 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) ?

解決方法は?

のソースコードを見ると 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];
}

7bit値ではそうなるようです。 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() はそれを呼び出すコードと同じアセンブリに存在するので、いずれにせよこれはうまくいかなかったかもしれません)。