none
Determine the .Net Type of the text comprising a constant. RRS feed

  • Question

  • Is there any support in place to take a string that contains the text of a literal C# constant, and then determine what type that would be according to C# rules?

    e.g.

    "'s'" -> type is Char
    "23" -> type is Byte
    "17.5" -> type is Single
    "true" -> type is Bool
    "32767" type is UInt64 (?)

    and so on.

    I could code this, but it might be error prone and contains inaccuracies, so if there is an existing way in the BCL or something that would be great. Failing that are the precise rules published that allows me to determine the type? including decimal, signed/unsigned and so on and so forth.

    Thanks

    Cap'n
    Monday, March 15, 2010 9:23 PM

Answers

  • Either use TryParse methods on the basic types (see example in System.Boolean.TryParse).

    Or if you want exact C# syntax, then you could probably use CodeDOM - generate code for each value: "dynamic v = yourvalue; return v.GetType();", but the perf will be horrible, so unless you need it just for some kind of scripting, I wouldn't use it.

    -Karel
    • Proposed as answer by tsadigov Tuesday, March 16, 2010 10:54 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:38 AM
    Monday, March 15, 2010 11:04 PM
    Moderator

All replies

  • Either use TryParse methods on the basic types (see example in System.Boolean.TryParse).

    Or if you want exact C# syntax, then you could probably use CodeDOM - generate code for each value: "dynamic v = yourvalue; return v.GetType();", but the perf will be horrible, so unless you need it just for some kind of scripting, I wouldn't use it.

    -Karel
    • Proposed as answer by tsadigov Tuesday, March 16, 2010 10:54 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:38 AM
    Monday, March 15, 2010 11:04 PM
    Moderator
  • Try to use .NET4 specific just in time compilation and then getType

    .NET guy
    Tuesday, March 16, 2010 10:54 AM
  • You do realize that there are many ambiguous cases, right?
    Say, "true" can either be a boolean or a string with the value "true".
    That second example of yours "23" can either be a byte, a short, an integer.
    "17.5" is a single? or a decimal? or a double?

    This means that the order in which you make the verifications in your algorithm is very important, because the TryParse will work for most cases, so what you have to do is make sure you verify the Byte type before the UInt32 and UInt16, etc...

    Also, be aware that methods like the TryParse will produce different results depending on the the current culture of the system. Details like the decimal separator being "." or "," make the difference here.

    -- Blog: http://geeklyeverafter.blogspot.com/
    Tuesday, March 16, 2010 2:16 PM
  • You do realize that there are many ambiguous cases, right?
    Say, "true" can either be a boolean or a string with the value "true".
    That second example of yours "23" can either be a byte, a short, an integer.
    "17.5" is a single? or a decimal? or a double?

    This means that the order in which you make the verifications in your algorithm is very important, because the TryParse will work for most cases, so what you have to do is make sure you verify the Byte type before the UInt32 and UInt16, etc...

    Also, be aware that methods like the TryParse will produce different results depending on the the current culture of the system. Details like the decimal separator being "." or "," make the difference here.

    -- Blog: http://geeklyeverafter.blogspot.com/

    I know what your saying but technically this isn't true.

    Firstly the lexeme: true has no quotes so is not a string, but the lexeme: "true" does have quotes, so is of course a string in this case.

    Secondly, the C# compiler assigns a type to every literal constant in your source code, it has rules for doing this.

    If it sees: 23  then it will assign a type of (I guess) of SByte to that, it does this for every constant in the source code, if it see Name.OtherName then it deduces the type from a knowledge of the declaration for those names in a symbol table and so on.

    What I want is to be able to do the same (but only for literal constants), give me a lexeme and I will return the same type the compiler would see.

    I'm thinking the the .Net 4 JIT and getType stuff I'm hearing about, is the way to go here though.

    Does my reply make sense?

    I see your point, but if you think about the compiler it doesn't see ambiguity, it has a set of rules for determing type from the lexical nature of the text.

    Cap'n

    Tuesday, March 16, 2010 2:41 PM
  • Either use TryParse methods on the basic types (see example in System.Boolean.TryParse).

    Or if you want exact C# syntax, then you could probably use CodeDOM - generate code for each value: "dynamic v = yourvalue; return v.GetType();", but the perf will be horrible, so unless you need it just for some kind of scripting, I wouldn't use it.

    -Karel

    Hmm this could work, the operation is performed rarely, in one-off initialization scenarios, so this could be fine, I will look into this.

    Thanks

    Cap'n

    Tuesday, March 16, 2010 2:47 PM
  • Firstly the lexeme: true has no quotes so is not a string, but the lexeme: "true" does have quotes, so is of course a string in this case.
    Secondly, the C# compiler assigns a type to every literal constant in your source code, it has rules for doing this. 
    I see your point, but if you think about the compiler it doesn't see ambiguity, it has a set of rules for determing type from the lexical nature of the text.
    I know the C# parser doesn't see this ambiguity, because the grammar has specific rules that are matched in a specific order to remove any possible ambiguity.
    I only mentioned the "true" string vs bool case because as you said, you wish to gather that information from a "string that contains the text of a literal C# constant". So, knowing that your information is already within a string, the issue remains as so, unless of course you're representing a string with that string with additional quotes. I'm not sure this is clear enough, what I'm saying is that a string your string containing a literal C# constant that represents in itself a string would be something like ""my string"". Right?

    Now concerning the C# rules, unless you find a way of doing it with the previously mentioned TryParse or CodeDom, maybe you could take a peek at some C# parser. Maybe the parser used in SharpDevelop (which is opensource) could give you the necessary hints.

    -- Blog: http://geeklyeverafter.blogspot.com/
    Tuesday, March 16, 2010 3:27 PM
  • Firstly the lexeme: true has no quotes so is not a string, but the lexeme: "true" does have quotes, so is of course a string in this case.
    Secondly, the C# compiler assigns a type to every literal constant in your source code, it has rules for doing this. 
    I see your point, but if you think about the compiler it doesn't see ambiguity, it has a set of rules for determing type from the lexical nature of the text.
    I know the C# parser doesn't see this ambiguity, because the grammar has specific rules that are matched in a specific order to remove any possible ambiguity.
    I only mentioned the "true" string vs bool case because as you said, you wish to gather that information from a "string that contains the text of a literal C# constant". So, knowing that your information is already within a string, the issue remains as so, unless of course you're representing a string with that string with additional quotes. I'm not sure this is clear enough, what I'm saying is that a string your string containing a literal C# constant that represents in itself a string would be something like ""my string"". Right?

    Now concerning the C# rules, unless you find a way of doing it with the previously mentioned TryParse or CodeDom, maybe you could take a peek at some C# parser. Maybe the parser used in SharpDevelop (which is opensource) could give you the necessary hints.

    -- Blog: http://geeklyeverafter.blogspot.com/
    Yes you are right, the string "hello" will be stored in a string variable quotes and all, you can assign that like this actually:

    string text = @"""hello""";

    If you dump that string in debug and carefully examine the underlying characters (e.g. in a memory dump window) you can see the quotes are themselves stored in the string, this is just what you would see if you coded a simple lexical analyzer in C# and read the source code directly, creating tokens from raw text.

    Cap'n


    Tuesday, March 16, 2010 6:20 PM