If you absolutely have to use the Chr method for legacy reasons of whatever, the best thing is to use it as a normal method.
If you don't want to import VisualBasic, or want to see how it works, Reflector gives a nice piece of code:
public static char Chr(int CharCode)
{
char ch;
if ((CharCode < -32768) || (CharCode > 0xffff))
{
throw new ArgumentException(Utils.GetResourceString("Argument_RangeTwoBytes1", new string[] { "CharCode" }));
}
if ((CharCode >= 0) && (CharCode <= 0x7f))
{
return Convert.ToChar(CharCode);
}
try
{
int num;
Encoding encoding = Encoding.GetEncoding(Utils.GetLocaleCodePage());
if (encoding.IsSingleByte && ((CharCode < 0) || (CharCode > 0xff)))
{
throw ExceptionUtils.VbMakeException(5);
}
char[] chars = new char[2];
byte[] bytes = new byte[2];
Decoder decoder = encoding.GetDecoder();
if ((CharCode >= 0) && (CharCode <= 0xff))
{
bytes[0] = (byte) (CharCode & 0xff);
num = decoder.GetChars(bytes, 0, 1, chars, 0);
}
else
{
bytes[0] = (byte) ((CharCode & 0xff00) >> 8);
bytes[1] = (byte) (CharCode & 0xff);
num = decoder.GetChars(bytes, 0, 2, chars, 0);
}
ch = chars[0];
}
catch (Exception exception)
{
throw exception;
}
return ch;
}
For an ASCII character, it just calls Convert.ToChar
, which is equivalent to (char)CharCode
. The first interesting thing is the call to Utils.GetLocaleCodePage
:
internal static int GetLocaleCodePage()
{
return Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage;
}
Though one might expect it the same as Encoding.Default
, it creates an encoding associated with the culture of the current thread, not the system. The rest is just stuffing the code into an array and using the encoding to decode it.
This method has one major caveat, as usual when dealing with encoding - it heavily depends on the current locale, and changing the culture of the current thread breaks all conversions for codes outside ASCII. But still, if that's what you want to do, here's a rough and short equivalent:
public static char Chr(int code)
{
var encoding = Encoding.GetEncoding(Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage);
return encoding.GetChars(BitConverter.GetBytes((ushort)code))[0];
}
This lacks some checks of the original method, especially the single-byte and range check.
Then there's a much simpler and much better method in VB.NET - ChrW for Unicode:
public static char ChrW(int CharCode)
{
if ((CharCode < -32768) || (CharCode > 0xffff))
{
throw new ArgumentException(Utils.GetResourceString("Argument_RangeTwoBytes1", new string[] { "CharCode" }));
}
return Convert.ToChar((int) (CharCode & 0xffff));
}
This again falls back to ToChar:
public static char ToChar(int value)
{
if ((value < 0) || (value > 0xffff))
{
throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
}
return (char) value;
}
As you can see, ChrW is just the same as plain old char
conversion... except for negative values! You know, although the character code has to fit into two bytes, it may have come from both signed or unsigned short, so the method makes sure it is the right number for both types of origin. If you want to take that into account, just do CharCode & 0xffff
.
So as you can see, Chr
is just Encoding.GetChars
where the encoding is the current thread's one, and ChrW
is just (char)CharCode
, except that both functions also handle negative values. There is no other difference.
As for the original part of your question, you can't convert from char
to string
because... there is no possible conversion. They don't inherit each other, so you can't cast them, neither do they have any user-defined conversion operators, and string
is not a primitive value type, so no built-in conversion either. VB.NET might allow you to do this, but all in all, it allows many worse things thanks to its ancient versions.
TL;DR Is (char)
equivalent to Chr
? Only for ASCII character code (0 to 127), otherwise no. And Chr
stops working if the current encoding and the code encoding differ, which matter if you use non-ASCII characters.