Why is Chr (3) a constant expression, but not Chr (172)?

If I write the following code, ReSharper will suggest converting the first variable chr3 to a constant, but not the second variable, 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 

If I convert both to constants, I get a Visual Studio compiler warning on Chr(172) , which states that the Constant expression is required ", but not a compiler warning for 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 

What makes Chr(3) constant expression, but not Chr(172) ?

+4
source share
2 answers

Having looked at the source code for Microsoft.VisualBasic.Strings.Chr() , I see the following (which I simplified for this post by removing exception handling):

 /// <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]; } 

It seems that for 7-bit values, Convert.ToChar(CharCode) returned, which I suppose the compiler is smart enough to conclude a constant, while for 8-bit values, the current CodePage culture is used, which will give different computer-based results, on which code works, and therefore can not be a constant.

Update: I tried to replicate the situation in a method that I wrote myself, but I can’t, which suggests that the compiler itself may have a special rule for evaluating constant expressions.

 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) 

(However, ConstOrNot() exists in the same assembly as the code that calls it, so this might not work.)

+1
source

Character 3 is the "end of text" symbol, so it seems unsurprising that it may exhibit strange behavior. This and other similar characters are rarely used directly.

+1
source

Source: https://habr.com/ru/post/1484529/


All Articles