Why does Integer.TryParse set result to zero on failure? - vb.net

My understanding of the Integer.TryParse() function was that it tried to parse an integer from the passed in string and if the parse failed the result integer would remain as it did before.
I have an integer with a default value of -1 which I would like to remain at -1 if the parse fails. However the Integer.TryParse() function on failing to parse is changing this default value to zero.
Dim defaultValue As Integer = -1
Dim parseSuccess As Boolean = Integer.TryParse("", defaultValue)
Debug.Print("defaultValue {0}", defaultValue)
Debug.Print("parseSuccess {0}", parseSuccess)
My expectation is that the code snippet above should output:
defaultValue -1
parseSuccess False
However instead it outputs:
defaultValue 0
parseSuccess False
Is my understanding correct?

It's an out parameter, which means it must be set by the method (unless it throws an exception) - the method can't see what the original value was.
The alternative would have been to make it a ref parameter and only set it on success, but that would mean forcing callers to initialize the variable first even if they didn't want this behaviour.
You can write your own utility method though:
public bool TryParseInt32(string text, ref int value)
{
int tmp;
if (int.TryParse(text, out tmp))
{
value = tmp;
return true;
}
else
{
return false; // Leave "value" as it was
}
}

You are correct, TryParse uses 0 if it fails. (MSDN says this quite clearly)
But you could check paseSuccess and return your default value if this is what you want to.

Related

Can you retry a Zig function call when it returns an error?

Zig's documentation shows different methods of error handling including bubbling the error value up the call stack, catching the error and using a default value, panicking, etc.
I'm trying to figure out how to retry functions which provide error values.
For example, in the below snippet from ziglearn, is there a way to retry the nextLine function in the event that a user enters greater than 100 characters?
fn nextLine(reader: anytype, buffer: []u8) !?[]const u8 {
var line = (try reader.readUntilDelimiterOrEof(
buffer,
'\n',
)) orelse return null;
// trim annoying windows-only carriage return character
if (#import("builtin").os.tag == .windows) {
return std.mem.trimRight(u8, line, "\r");
} else {
return line;
}
}
test "read until next line" {
const stdout = std.io.getStdOut();
const stdin = std.io.getStdIn();
try stdout.writeAll(
\\ Enter your name:
);
var buffer: [100]u8 = undefined;
const input = (try nextLine(stdin.reader(), &buffer)).?;
try stdout.writer().print(
"Your name is: \"{s}\"\n",
.{input},
);
}
This should do what you want.
const input = while (true) {
const x = nextLine(stdin.reader(), &buffer) catch continue;
break x;
} else unreachable; // (see comment) fallback value could be an empty string maybe?
To break it down:
instead of try, you can use catch to do something in the case of an error, and we're restarting the loop in this case.
while loops can also be used as expressions and you can break from them with a value. they also need an else branch, in case the loop ends without breaking away from it. in our case this is impossible since we're going to loop forever until nextLine suceeds, but if we had another exit condition (like a limit on the number of retries), then we would need to provide a "fallback" value, instead of unreachable.
You can also make it a one-liner:
const input = while (true) break nextLine(stdin.reader(), &buffer) catch continue else unreachable;
Hopefully the new self-hosted compiler will be able to pick up on the fact that the else branch is not necessary, since we're going to either break with a value loop forever.

How to change the value of a string in Kotlin after it has already been initialised?

I'm trying to code this problem: Initialise a String as “Hello, Kotlin” and change its value to null. Now print the length of the String using safe call and non-null assertion operator.
I know how to initialise a string with null value, but don't know how to set it as null after it's been already initialised with a different string value.
To set null in a variable it needs to be declared as nullbable.
fun main() {
var srt: String? = "Hello, Kotlin"
println(srt)
srt = null
println(srt)
}

Room database query returns null where it should be null-safe in Kotlin

I have a query that does not have a result, when the DB is empty. Therefore NULL is the correct return value.
However, the compiler in Android Studio gives me the warning: Condition 'maxDateTime != null' is always 'true'.
If I debug the code, the null check performs correctly as the value is actually null.
When I rewrite the interface to 'fun queryMaxServerDate(): String?' (notice the question mark), the compiler warning goes away.
But should not 'fun queryMaxServerDate(): String' result in a compilation error since it can be null?
#Dao
interface CourseDao {
// Get latest downloaded entry
#Query("SELECT MAX(${Constants.COL_SERVER_LAST_MODIFIED}) from course")
fun queryMaxServerDate(): String
}
// calling function
/**
* #return Highest server date in table in milliseconds or 1 on empty/error.
*/
fun queryMaxServerDateMS(): Long {
val maxDateTime = courseDao.queryMaxServerDate()
var timeMS: Long = 0
if (maxDateTime != null) { // Warning: Condition 'maxDateTime != null' is always 'true'
timeMS = TimeTools.parseDateToMillisOrZero_UTC(maxDateTime)
}
return if (timeMS <= 0) 1 else timeMS
}
The underlying code generated by the annotation is java and thus the exception to null safety as per :-
Kotlin's type system is aimed to eliminate NullPointerException's from
our code. The only possible causes of NPE's may be:
An explicit call to throw NullPointerException(); Usage of the !!
operator that is described below;
Some data inconsistency with regard
to initialization, such as when:
An uninitialized this available in a
constructor is passed and used somewhere ("leaking this");
A
superclass constructor calls an open member whose implementation in
the derived class uses uninitialized state;
Java interoperation:
Attempts to access a member on a null reference of a platform type;
Generic types used for Java interoperation with incorrect nullability,
e.g. a piece of Java code might add null into a Kotlin
MutableList, meaning that MutableList should be used
for working with it;
Other issues caused by external Java code.
Null Safety
e.g. the generated code for queryMaxServerDate() in CourseDao would be along the lines of :-
#Override
public String queryMaxServerDate() {
final String _sql = "SELECT max(last_mopdified) from course";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
__db.assertNotSuspendingTransaction();
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
final String _result;
if(_cursor.moveToFirst()) {
final String _tmp;
_tmp = _cursor.getString(0);
_result = _tmp;
} else {
_result = null;
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
As you can see, no data extracted (no first row) and null is returned.

Char.IsSymbol("*") is false

I'm working on a password validation routine, and am surprised to find that VB does not consider '*' to be a symbol per the Char.IsSymbol() check.
Here is the output from the QuickWatch:
char.IsSymbol("*") False Boolean
The MS documentation does not specify what characters are matched by IsSymbol, but does imply that standard mathematical symbols are included here.
Does anyone have any good ideas for matching all standard US special characters?
Characters that are symbols in this context: UnicodeCategory.MathSymbol, UnicodeCategory.CurrencySymbol, UnicodeCategory.ModifierSymbol and UnicodeCategory.OtherSymbol from the System.Globalization namespace. These are the Unicode characters designated Sm, Sc, Sk and So, respectively. All other characters return False.
From the .Net source:
internal static bool CheckSymbol(UnicodeCategory uc)
{
switch (uc)
{
case UnicodeCategory.MathSymbol:
case UnicodeCategory.CurrencySymbol:
case UnicodeCategory.ModifierSymbol:
case UnicodeCategory.OtherSymbol:
return true;
default:
return false;
}
}
or converted to VB.Net:
Friend Shared Function CheckSymbol(uc As UnicodeCategory) As Boolean
Select Case uc
Case UnicodeCategory.MathSymbol, UnicodeCategory.CurrencySymbol, UnicodeCategory.ModifierSymbol, UnicodeCategory.OtherSymbol
Return True
Case Else
Return False
End Select
End Function
CheckSymbol is called by IsSymbol with the Unicode category of the given char.
Since the * is in the category OtherPunctuation (you can check this with char.GetUnicodeCategory()), it is not considered a symbol, and the method correctly returns False.
To answer your question: use char.GetUnicodeCategory() to check which category the character falls in, and decide to include it or not in your own logic.
If you simply need to know that character is something else than digit or letter,
use just
!char.IsLetterOrDigit(c)
preferably with
&& !char.IsControl(c)
Maybe you have the compiler option "strict" of, because with
Char.IsSymbol("*")
I get a compiler error
BC30512: Option Strict On disallows implicit conversions from 'String' to 'Char'.
To define a Character literal in VB.NET, you must add a c to the string, like this:
Char.IsSymbol("*"c)
IsPunctuation(x) is what you are looking for.
This worked for me in C#:
string Password = "";
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
// Ignore any key out of range.
if (char.IsPunctuation(key.KeyChar) ||char.IsLetterOrDigit(key.KeyChar) || char.IsSymbol(key.KeyChar))
{
// Append the character to the password.
Password += key.KeyChar;
Console.Write("*");
}
// Exit if Enter key is pressed.
} while (key.Key != ConsoleKey.Enter);

Passing null to an optional parameter with default value

I think this is a pretty basic question, but I just want to clarify. If I have a variable with a null value, and pass it as a parameter that is optional, will the parameter get the null value, or the default value?
dim str As String = "foo"
dim obj As Object
//call 1
Request(str, str)
//call 2
Request(str)
//call 3
Request(str, obj)
public Function Request(byVal someVal As String, Optional ByVal someVal2 As String = "bar")
...
I know that call 1 will make someval == someval2 == "foo" inside the function, and call 2 will make someval == "foo" and someval2 == "bar" and call 3 will make someval == foo but what is someval2 equal to in call 3? nullable or bar?
Also - I'm relatively new to vb.net and I don't think I fully understand the null/nullable/nothing concept differences from C#
"what is someval2 equal to in call 3? nullable or bar?" It will be null.
Well, actually, you can't do call 3 ... it will not compile because you can't pass an object as a string parameter. However, if you had dim obj as string = null, then it would be null.
If no parameter value is supplied to an optional parameter, the default value for that parameter will be used.
If Nothing is passed to an optional parameter, the parameter value will be Nothing and the default value will be ignored.