String interpolation outputs enum name instead of value - vb.net

I was hoping someone can explain this default functionality regarding string interpolation and the enum type.
I have this enum:
public enum CommentType
{
MyComment = 24,
TheirComment = 25,
AnotherComment = 26
}
I am using it in a string:
Dim sDateModified As String
sDateModified = $"<div name='commenttype{CommentType.MyComment}'></div>"
I was expecting CommentType.MyComment to be evaluated and the int value 24 to be used. The result should be: <div name='commenttype24'></div>
But what actually happens is that the identifier is used instead, giving me: <div name='commenttypeMyComment'></div>
In order to get the enum value I had to convert it to an integer:
sDateModified = $"<div name='commenttype{Convert.ToInt32(CommentType.MyComment)}'></div>"
It just feels counter intuitive to me. Can someone explain or point me to documentation on why it works this way?

You're getting the string value MyComment because that's what is returned by:
CommentType.MyComment.ToString()
Methods like String.Format and Console.WriteLine will automatically call ToString() on anything that isn't already a string. The string interpolation syntax $"" is just syntactic sugar for String.Format, which is why string interpolation also behaves this way.
Your workaround is correct. For slightly more compact code, you could do:
CInt(CommentType.MyComment)

You just need to use a format string in the interpolated value to force the result to integer format.
Dim sDateModified As String
sDateModified = $"<div name='commenttype{CommentType.MyComment:D}'></div>"

Related

How to serialize an object with newtonsoft, which has a value with backslash [\]

I prepared this small example to show you my problem (vb.net and Newtonsoft)
I would prefer that the solution be done with Newtonsoft.
Public Class Message
Property Emoji As String
End Class
Public Sub GetJson()
Dim msgObject As New Message With {.Emoji = "\uD83D\uDE00"}
'Option 1
Dim JsonSerializerSettings As New JsonSerializerSettings
JsonSerializerSettings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
Dim msgJson_1 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, JsonSerializerSettings)
'Option 2
Dim msgJson_2 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, Newtonsoft.Json.Formatting.None)
'Option 3
Dim stringWriter As New StringWriter()
Using writer As New JsonTextWriter(stringWriter)
writer.Formatting = Formatting.None
Dim serializer As New JsonSerializer()
serializer.Serialize(writer, msgObject)
End Using
Dim msgJson_3 As String = stringWriter.ToString()
End Sub
with none of the three options works, it always results in
{
"Emoji": "\\uD83D\\uDE00"
}
The result I need is
{
"Emoji": "\uD83D\uDE00"
}
How do I set Newtonsoft to not take into account the backslash character, as an escaped character?
Another unorthodox way could be:
jsonString = jsonString.replace("\\","\")
I do not really like
Thanks!!!!
\ is an escape char in JSON hence if you try and serialise a \ it gets escaped as \\ then when you deserialise \\ you get \
My guess is you have been given an example asking you to send "Emoji": "\uD83D\uDE00"
In json (and C#) \u#### specifies a unicode character (usually for something not found on a keyboard) as you are using VB.NET instead you should use $"{ChrW(&HD83D)}{ChrW(&HDE00)}"
"jsonString = jsonString.replace("//","/") " will never work, this is more safe way
json = json.Replace("\\\\u","\\u");
or since you don't like old, good classical solutions
json = Regex.Replace(json, #"\\u", #"u");
//or
json = json.Replace(#"\\u", #"\u");
even this will work in your case ( but I will not recommend for another cases since it is not safe)
json = Regex.Unescape(json);

calling a double from object seems to return the possition not value of the double

In a function i have this:
val sunRise = SunEquation(2459622)
binding.timeDisplay.setText("$sunRise.n")
The SunEquation-Class looks like this:
class SunEquation(var jDate: Int,) {
val jYear = 2451545
val ttOffset = .0008
var n = jDate - jYear + ttOffset
}
the button- text that appears is:
com.example.soluna.SunEquation#6d1a94b.n
i would expect a double-value
You have to add curly brackets around the value you want to inject into the String, like this:
binding.timeDisplay.setText("${sunRise.n}")
The shorthand syntax without brackets only works for a single variable, but not
for access to a nested field or other more complex expressions.
In your case, this results in the object itself being injected into the String, which is resembled by com.example.soluna.SunEquation#6d1a94b based on the result of the corresponding toString() call, which defaults to the class name and the reference id of the object. Followed by the literal String .n.
Alternatively, you could extract the value into a val beforehand and reference that.
val customN = sunRise.n
binding.timeDisplay.setText("$customN")

Getting the name of the variable as a string in GD Script

I have been looking for a solution everywhere on the internet but nowhere I can see a single script which lets me read the name of a variable as a string in Godot 3.1
What I want to do:
Save path names as variables.
Compare the name of the path variable as a string to the value of another string and print the path value.
Eg -
var Apple = "mypath/folder/apple.png"
var myArray = ["Apple", "Pear"]
Function that compares the Variable name as String to the String -
if (myArray[myposition] == **the required function that outputs variable name as String**(Apple) :
print (Apple) #this prints out the path.
Thanks in advance!
I think your approach here might be a little oversimplified for what you're trying to accomplish. It basically seems to work out to if (array[apple]) == apple then apple, which doesn't really solve a programmatic problem. More complexity seems required.
First, you might have a function to return all of your icon names, something like this.
func get_avatar_names():
var avatar_names = []
var folder_path = "res://my/path"
var avatar_dir = Directory.new()
avatar_dir.open(folder_path)
avatar_dir.list_dir_begin(true, true)
while true:
var avatar_file = avatar_dir.get_next()
if avatar_file == "":
break
else:
var avatar_name = avatar_file.trim_suffix(".png")
avatar_names.append(avatar_name)
return avatar_names
Then something like this back in the main function, where you have your list of names you care about at the moment, and for each name, check the list of avatar names, and if you have a match, reconstruct the path and do other work:
var some_names = ["Jim","Apple","Sally"]
var avatar_names = get_avatar_names()
for name in some_names:
if avatar_names.has(name):
var img_path = "res://my/path/" + name + ".png"
# load images, additional work, etc...
That's the approach I would take here, hope this makes sense and helps.
I think the current answer is best for the approach you desire, but the performance is pretty bad with string comparisons.
I would suggest adding an enumeration for efficient comparisons. unfortunately Godot does enums differently then this, it seems like your position is an int so we can define a dictionary like this to search for the index and print it out with the int value.
var fruits = {0:"Apple",1:"Pear"}
func myfunc():
var myposition = 0
if fruits.has(myposition):
print(fruits[myposition])
output: Apple
If your position was string based then an enum could be used with slightly less typing and different considerations.
reference: https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html#enums
Can't you just use the str() function to convert any data type to stirng?
var = str(var)

How to convert Object(with value) into Map

I have a object that I want to print it into string [key1=value1&key2=value2...etc] without the null value key value pair and comma into &.
So first of all i think of putting it into a map but it won't work and I don know how it work either.
val wxPayOrderObj = WxPayOrder(appid = "wx0b6dcsad20b379f1", mch_id =
"1508334851", nonce_str = UUID.randomUUID().toString(),sign = null,
body = "QQTopUp", out_trade_no = "20150806125346", total_fee = req.total_fee,
spbill_create_ip = "123.12.12.123",
trade_type = "JSAPI", openid = "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o")
so the output will be
appid=wx0b6dc78d20b379f1&mch_id=150788851&nonce_str=UUID.randomUUID().toString()&
body=QQTopUp&out_trade_no=20150806125346&total_fee=req.total_fee&
spbill_create_ip=123.12.12.123&trade_type=JSAPI&openid=oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
anyone please help me, thanks in advances.
I don't really get your question, but you want to convert object to string (to a format that you want)?
Override the object's toString() to return "[key1=value1&key2=value2...etc]"
example
override fun toString(){
// make sure you compute the data first
val answer = "[key1=$value1&key2=$value2...etc]"
return answer
}
The $ is used in string templates (That's directly writing the name of a variable, the value will be used later to be concatenated) with other strings)

VB.NET String.Format FormatException was unhandled

I want to generate a json string but
What did I do is wrong? Why to this code throws an An unhandled exception
Public Function GenerateJsonString(doer As Integer, comment As String, id As Integer) As String
Dim jsonString As String = String.Format("{done_by:{0}, comment:{1}, request_id:{2}}", doer, comment, id)
Return jsonString
End Function
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll
Additional information: Input string was not in a correct format.
The bracket { is a special character in string.format so you need to use two brackets if you want them in the output like so:
Dim jsonString As String = String.Format("{{done_by:{0}, comment:{1}, request_id:{2}}}", 806, "comment", 16233)
It outputs
{done_by:806, comment:comment, request_id:16233}
Which is not valid json since it's missing the "-characters. So to correct that you could do
Dim jsonString As String = String.Format("{{""done_by"":{0}, ""comment"":""{1}"", ""request_id"":{2}}}", 806, "comment", 16233)
Note that comment is string and also needs the "-characters in value.
Output is correct json:
{"done_by":806, "comment":"comment", "request_id":16233}
There is also easier and more robust way to do this by serialization:
Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim jsonString As String = serializer.Serialize(New With {.done_by = 806, .comment = "comment", .request_id = 16233})
If you have class library or windows -project it needs System.Web.Extensions reference to your project.
Good luck!
The issue is the fact that you have braces in your literal text. When calling String.Format, braces are used to indicate place-holders but you have an opening brace at the beginning of the text and a closing brace at the end. If you want those literal braces included then you must escape them, i.e.
"{{done_by:{0}, comment:{1}, request_id:{2}}}"