What's the equivalent of VB's Asc() and Chr() functions in C#?

96,452

Solution 1

You could always add a reference to Microsoft.VisualBasic and then use the exact same methods: Strings.Chr and Strings.Asc.

That's the easiest way to get the exact same functionality.

Solution 2

For Asc() you can cast the char to an int like this:

int i = (int)your_char;

and for Chr() you can cast back to a char from an int like this:

char c = (char)your_int;

Here is a small program that demonstrates the entire thing:

using System;

class Program
{
    static void Main()
    {
        char c = 'A';
        int i = 65;

        // both print "True"
        Console.WriteLine(i == (int)c);
        Console.WriteLine(c == (char)i);
    }
}

Solution 3

I got these using resharper, the exact code runs by VB on your machine

/// <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 <paramref name="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) short.MinValue || CharCode > (int) ushort.MaxValue)
    throw new ArgumentException(Utils.GetResourceString("Argument_RangeTwoBytes1", new string[1]
    {
      "CharCode"
    }));
  if (CharCode >= 0 && CharCode <= (int) sbyte.MaxValue)
    return Convert.ToChar(CharCode);
  try
  {
    Encoding encoding = Encoding.GetEncoding(Utils.GetLocaleCodePage());
    if (encoding.IsSingleByte && (CharCode < 0 || CharCode > (int) byte.MaxValue))
      throw ExceptionUtils.VbMakeException(5);
    char[] chars = new char[2];
    byte[] bytes = new byte[2];
    Decoder decoder = encoding.GetDecoder();
    if (CharCode >= 0 && CharCode <= (int) byte.MaxValue)
    {
      bytes[0] = checked ((byte) (CharCode & (int) byte.MaxValue));
      decoder.GetChars(bytes, 0, 1, chars, 0);
    }
    else
    {
      bytes[0] = checked ((byte) ((CharCode & 65280) >> 8));
      bytes[1] = checked ((byte) (CharCode & (int) byte.MaxValue));
      decoder.GetChars(bytes, 0, 2, chars, 0);
    }
    return chars[0];
  }
  catch (Exception ex)
  {
    throw ex;
  }
}


/// <summary>
/// Returns an Integer value representing the character code corresponding to a character.
/// </summary>
/// 
/// <returns>
/// Returns an Integer value representing the character code corresponding to a character.
/// </returns>
/// <param name="String">Required. Any valid Char or String expression. If <paramref name="String"/> is a String expression, only the first character of the string is used for input. If <paramref name="String"/> is Nothing or contains no characters, an <see cref="T:System.ArgumentException"/> error occurs.</param><filterpriority>1</filterpriority>
public static int Asc(char String)
{
  int num1 = Convert.ToInt32(String);
  if (num1 < 128)
    return num1;
  try
  {
    Encoding fileIoEncoding = Utils.GetFileIOEncoding();
    char[] chars = new char[1]
    {
      String
    };
    if (fileIoEncoding.IsSingleByte)
    {
      byte[] bytes = new byte[1];
      fileIoEncoding.GetBytes(chars, 0, 1, bytes, 0);
      return (int) bytes[0];
    }
    byte[] bytes1 = new byte[2];
    if (fileIoEncoding.GetBytes(chars, 0, 1, bytes1, 0) == 1)
      return (int) bytes1[0];
    if (BitConverter.IsLittleEndian)
    {
      byte num2 = bytes1[0];
      bytes1[0] = bytes1[1];
      bytes1[1] = num2;
    }
    return (int) BitConverter.ToInt16(bytes1, 0);
  }
  catch (Exception ex)
  {
    throw ex;
  }
}


/// <summary>
/// Returns an Integer value representing the character code corresponding to a character.
/// </summary>
/// 
/// <returns>
/// Returns an Integer value representing the character code corresponding to a character.
/// </returns>
/// <param name="String">Required. Any valid Char or String expression. If <paramref name="String"/> is a String expression, only the first character of the string is used for input. If <paramref name="String"/> is Nothing or contains no characters, an <see cref="T:System.ArgumentException"/> error occurs.</param><filterpriority>1</filterpriority>
public static int Asc(string String)
{
  if (String == null || String.Length == 0)
    throw new ArgumentException(Utils.GetResourceString("Argument_LengthGTZero1", new string[1]
    {
      "String"
    }));
  return Strings.Asc(String[0]);
}

Resources are just stored error message, so somehow the way you want ignore them, and the other two method which you do not have access to are as follow:

internal static Encoding GetFileIOEncoding()
{
    return Encoding.Default;
}

internal static int GetLocaleCodePage()
{
    return Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage;
}

Solution 4

Strings.Asc is not equivalent with a plain C# cast for non ASCII chars that can go beyond 127 code value. The answer I found on https://social.msdn.microsoft.com/Forums/vstudio/en-US/13fec271-9a97-4b71-ab28-4911ff3ecca0/equivalent-in-c-of-asc-chr-functions-of-vb?forum=csharpgeneral amounts to something like this:

    static int Asc(char c)
    {
        int converted = c;
        if (converted >= 0x80)
        {
            byte[] buffer = new byte[2];
            // if the resulting conversion is 1 byte in length, just use the value
            if (System.Text.Encoding.Default.GetBytes(new char[] { c }, 0, 1, buffer, 0) == 1)
            {
                converted = buffer[0];
            }
            else
            {
                // byte swap bytes 1 and 2;
                converted = buffer[0] << 16 | buffer[1];
            }
        }
        return converted;
    }

Or, if you want the read deal add a reference to Microsoft.VisualBasic assembly.

Solution 5

For Chr() you can use:

char chr = (char)you_char_value;
Share:
96,452
Shaul Behr
Author by

Shaul Behr

Husband, father, grandfather, software architect, Orthodox rabbi, fiction author, fitness enthusiast. https://shaulbehr.com

Updated on June 04, 2021

Comments

  • Shaul Behr
    Shaul Behr about 3 years

    VB has a couple of native functions for converting a char to an ASCII value and vice versa - Asc() and Chr().

    Now I need to get the equivalent functionality in C#. What's the best way?

  • Samuel
    Samuel over 15 years
    If you add a reference, it will exist.
  • MarkJ
    MarkJ over 11 years
    -1 because this is wrong. VB.Net Asc doesnt return ASCII codes, nor does it return Unicode codes. It returns "ANSI" codes in the current Windows code page (i.e. depends on current thread's locale). The cast will return a Unicode code point. Different for most characters on most locales. Use Microsoft.VisualBasic.Strings.Asc and Chr.
  • MarkJ
    MarkJ over 11 years
    +1 For actually being right, unlike all the other answers. They use different encodings from VB Asc and Chr and are wrong.
  • supercat
    supercat over 11 years
    @MarkJ: I suspect most common uses of Asc and Chr use values in the range 0-126, which the programmer would expect to map to the corresponding Unicode code points; even if there were a system where, e.g., Chr(34) would yield rather than ", I would think the programmer who wrote Chr(34) probably intended ".
  • JDB
    JDB over 11 years
    I have to agree with @MarkJ - I tried this code and it returns the same results for some characters (a-z, for example) but different results for others ("<", etc.).
  • Sadiq
    Sadiq over 9 years
    Yes, results are not same: {case 1. Strings.Chr(128) result 1: 8364 '€'} { case 2. (char) 128 result 2: 128 '(a box value) '} Besides, in 2nd case any value greater than 128 returns 'a box value' instead of a valid character.
  • Jeff
    Jeff about 9 years
    Please see Garry Shutler's answer below which is correct.
  • Jeff
    Jeff about 9 years
    This should have been the accepted answer for this question.
  • Maury Markowitz
    Maury Markowitz almost 9 years
    VisualBasic does not exist in any of the portable libraries. This will work only under classic Windows OS's.
  • Blue
    Blue over 6 years
    Welcome to Stack Overflow! While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations!
  • Tom Blodget
    Tom Blodget over 6 years
    Asc and Chr don't involve ASCII or even ISO 8859-1 (which is what your code does). They involve Encoding.Default.
  • HackSlash
    HackSlash about 6 years
    Thanks! I see the line I need is Convert.ToChar(CharCode); and I can handle the checking in my own code instead of importing VB!
  • Chris M.
    Chris M. over 5 years
    This function works correctly for me. Casting, as this answer indicated, does not work correctly for non ASCII characters beyond 127. I do not recommend referencing the VisualBasic assembly in your C# project. If you are going to do that, then you might as well create a VB project.
  • Chris M.
    Chris M. over 5 years
    Simply casting is not an equivalent to the Stings,Asc function. You will not always return the correct value.
  • Johny
    Johny over 4 years
    This solution doesn't work for me as I have a .netstandard lib and Microsoft.VisualBasic for netstandard doesn't support ASC
  • qtg
    qtg over 3 years
    I replace Utils.GetFileIOEncoding() with System.Text.Encoding.Default
  • Wolfgang Grinfeld
    Wolfgang Grinfeld about 3 years
    Encoding.Default will not always work in netstandard 2.0
  • Wolfgang Grinfeld
    Wolfgang Grinfeld about 3 years
    Encoding.Default will not always work in netstandard 2.0
  • Wolfgang Grinfeld
    Wolfgang Grinfeld about 3 years
    Encoding.Default works differently under .net Framework vs .netstandard 2.0
  • Wolfgang Grinfeld
    Wolfgang Grinfeld about 3 years
    Encoding.Default works differently between .NetStandard 2.0 and .NetFramework 4.x. At least when called from VB6 via COM Interop.
  • Hassan Faghihi
    Hassan Faghihi about 3 years
    @WolfgangGrinfeld Unfortunately, it Is long time since I hade issue working with both C# and VB, so I'm unaware of many thing these days