What are the best practices for safely parsing a string? - c#

what are the best practices for type conversions in C# ?
int temp=System.ConvertToInt32(Request.QueryString["Id"]);
if (temp!=null)
{ // logic goes here }
This fails if Id somehow turns out to be 'abc'
Please advice the use of of ternary operators and other single line statements apart from if else statements (like using single line ternary operators). Also, do you guys prefer TryParse over Convert & why so ? Have your say fellows.

TryParse has the obvious advantage that in the case of failure it will return false instead of throwing an exception.
The standard pattern would be something like:
int value;
if (int.TryParse(Request.QueryString["Id"], out value))
{
// Use value
}
else
{
// Do whatever you want on failure
}
Now, it's also worth bearing in mind that you can give int.TryParse an IFormatProvider and a NumberStyles - for example, you may well want to specify CultureInfo.InvariantCulture as the IFormatProvider if this is really meant to be an auto-generated ID (rather than one entered by a user).
If you want to effectively have "default values" you could write a helper method like this:
public static int? NullableTryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? value : (int?) null;
}
You can then use this like so:
int value = NullableTryParseInt32(text) ?? 10;
Or you could just write a method which takes a default value, of course :)

When it comes to solving any problem that has several similar solutions I also try to find the one that express to the reader of the code what I'm trying to accomplish the cleæret. In my oppinion that means going for the .TryParse in this particular case.
Using TryParse tells the reader that you are not guaranteed that the input is valid (if you were i'd use parse instead)
And since you are actually trying to parse the input as an int you might as well let the code read Line your intentions

You have two ways to do that
int i;
if (Int32.TryParse(Request.QueryString["Id"], out i))
{
}
or you can do:
try
{
Convert.ToInt32(Request.QueryString["Id"]);
}
catch (FormatException ex)
{
// The field Id it's not convertible
}
catch (Exception ex)
{
// It could throw also ArgumentException or OverflowException
}

It would seem that this:
http://www.kodefuguru.com/post/2010/06/24/TryParse-vs-Convert.aspx
answers your question

Using TryParse would be the best option. Catching exception from convert method is expensive operation. Of course TryParse would only accepts strings while Convert.ToInt32 will take object and can perform conversions (unboxing, down-casting from long/double) apart from parsing.

To cover the ternary operator aspect of this question:
My advice on the use of ternary operators is not to use them if you aren't already so familiar with the code in question that it reads naturally to you. Concision makes the familiar more familiar and the strange, stranger.
When you've groked the discussion about TryParse here enough that you don't even need to think it through conciously anymore, the conversion from if-else to ?: will not just be trivial, it'll be automatic. Until then you're just going to add to your own confusion.
When I'm unfamiliar with something, I drop down to "baby-speak" code at first, learn the new thing, and then integrate it into my normal more concise style after.

use the TryParse method of the int class.
int temp;
if (int.TryParse(Request.QueryString["Id"], out temp)
{ // logic goes here }
If id does not contain a number TryParse will return false.
UPDATE: Changed to show int.TryParse

Related

Null safe string

I have a localzation string which apparently if set to null is causing issues in the view. So my solution was to string it.
_localizer["Controller_Account_ResetPassword_ResetFailed"].ToString();
During code review my co-worker reminded me that .ToString() is not null safe. While its highly unlikely that a localization would be null I guess it could be. He suggested the following.
TempData["Message"] = $"{_localizer["Controller_Account_ResetPassword_ResetFailed"]}";
I have two questions.
Why is $"{var}" null safe and .ToString() is not.
Is there a better way of doing it because his solution seams ugly to me.
First of all, the reason is that it's basically decompiled as
var arg = _localizer["Controller_Account_ResetPassword_ResetFailed"];
string.Format("{0}", arg);
and string.Format does a null check on its arguments and automatically replaces them with string.Empty.
Second of all, this solution is beautiful and string interpolation is an ingenious tool. You should use it :)
EDIT:
I kinda overlooked the fact here string interpolation is used solely to fix the null problem. As some have pointed out that is unnecessary and as much as everyone should love string interpolation something like this:
_localizer["Controller_Account_ResetPassword_ResetFailed"]?.ToString() ?? "";
would be a better choice.
I like to use a ToStringSafe extension method for these kind of scenarios
public static class Extensions
{
public static string ToStringSafe(this object value)
{
// return empty string
if (value == null) {
return String.Empty;
}
return value.ToString();
}
}
You can use the ?? operator to substitute "" if needed:
var something = _localizer["Controller_Account_ResetPassword_ResetFailed"] ?? "";
I wouldn't use $"{value}" notation here. First of all it probably is unneeded, second it does extra work by calling string.Format() which internally creates a StringBuilder object.
It also is by no means clear that the only and actual reason for calling $"{value}" would be to deal with a potential null value, which is 100% clear when you use ??.
As it was stated above the string interpolation is null-safe as it's converted internally to the string.Format. However to answer the second question the information of how you're going to handle rare case with null localization is required. The solution suggested by your colleague is good (I'd only recommend to extract the variable instead of inlining for better readability), but you possibly may want to fall back to the non-localized version of the message instead of getting empty string in case of localization absence or handle the situation in any other way. In that case you'll have to do the explicit null verification possibly inside the _localizer type implementation so that it's always guaranteed to return non-null values or fail.

Is it a good practice not to use returned value of a method?

Here's my method:
public static bool ValidateAddressCount(ref long o_addressCount)
{
// o_addressCount is modified here
//return true or false
}
I've reached some case when i don't care what the method returns, i just need the o_adressCount
Is it a good practice to use this method in the following way:
long addressCount = 0;
ValidateAddressCount(ref addressCount); //without assigning the returned value to any variable
//use address count
Also, can anyone explain why this works in .net?
Thank you
Its upto the developer. No hard rules in it.
Like in bool int.TryParse(string s, out int a){}
When we pass a value to be converted into int value it returns a bool value and uses the out variable to send converted value.
Sometimes we need to check whether it has been converted or not. That's where we use return value.
string str = "1";
int a = 0;
if(int.TryParse(str, out a))
MessageBox.Show("Converted");
else
MessageBox.Show("Not Converted");
Tryparse can be used simply as
bool b = int.TryParse(str, out a);
Let's say bool value returned is of no use to me. Then why waste memory by creating a variable(b), assigning it a value and not using it. So i will write it as
int.TryParse(str, out a);
Why it works is easy:
long addressCount = 0;
ValidateAddressCount(ref addressCount);
is of the same form as
long addressCount = 0;
true;
Any <expression> ; is a valid statement.
There is a valid question here though:
Why is there no warning for this syntax which is quite likely a mistake?
Because in general it is not a good practice to ignore a return value.
This works because you declared a method with return-value, which means that you may want care about that return-value, but it's not mandatory option.
Use ref/out when calling method want the changes of called method in passed parameter.
Otherwise, it's not a good choice to use ref/out.
You should use dynamic object/tuple if want to return more than one value from called method.
You do not have to use the result of the method, you can just call it for its side effect. However, it's usually a good idea to avoid using ref, if you can. In your case, you can just return long?.
No you dont need to assign the return value.. but in my opinion, method as validateSomething(object) should have a return value if the object is valid or not and it shoud be important to check for the return value.
If the method does something with the object, it shouldnt be called just validateSomething(object), but validateAndChangeSomething(object)... now it is confusing what it is doing and what is the primary output of the validation: the return value or the modified object..
Whilst what you have written works, I don't think it's particularly obvious what your method is doing.
Things have moved on a bit since I first started coding but I believe that nowdays it good practice to make your code readable to humans first and then comment the hell out of it if you really have to do something unexpected.
With that in mind, I'd tweak your code to provide a property to obtain the count and modify the method so that you wouldn't need a parameter.
I know this doesn't answer the "use a method and ignore the return type" part of your question but I think that's subjective on what your are doing at the time.

usages of out parameter in conditional flow and CA1002 fxcop error

I have a xml parsing code where I am parsing multiple nodes and attributes from xml. Using short circuit, I am able to avoid if in my code because I want to continue processing only in positive case. But I am getting fxcop error CA1002 for parameter as out usages.
How can I remove the fxcorp error?
public bool parseNode()
{
bool success = false;
string val1;
string val2;
string val3
success = TryGetAttributeValue(attribName1, out val1) &&
TryGetAttributeValue(attribName2, out val2) &&
TryGetAttributeValyue(attribName3, out val3);
if(success)
{
// do work
}
}
public bool TryGetAttributeValue(string attribName, out string value)
{
}
Assuming you're talking about CA1021 (Avoid out parameters) and not CA1002 (Do not expose generic lists), FxCop is complaining about the out parameter of your TryGetAttributeValue() method.
You can refactor that method so it returns the attribute value instead of storing it in an out parameter, and have it return nullif the attribute does not exist. From there, you can use the null-coalescing operator ?? to keep the same control flow:
public string TryGetAttributeValue(string attribName)
{
// Return attribute value, or null.
}
public bool ParseNode()
{
if ((TryGetAttributeValue(attribName1)
?? TryGetAttributeValue(attribName2)
?? TryGetAttributeValue(attribName3)) != null) {
// Do work.
}
}
Are you sure it's CA1002? Because that one is the Do not expose generic lists rule according to google. Anyway, I know that FxCop has rule which warns about using out (and also ref) parameters as they are not considered best practice for OO (your are supposed to return a object which represents the result).
In order to get rid of the warning you would need to change your method TryGetAttributeValue to not use out parameters.
As a side note: Microsoft apparently violated this rule in the various TryGet and TryParse methods. So just because FxCop says so, it does not make it necessarily a bad choice.
Assuming you are actually talking about CA1021, which fits your description better: This is the MSDN article about this violation. You can change the method type to something other than public or protected (internal ?)
Otherwise:
To fix a violation of this rule that is caused by a value type, have
the method return the object as its return value. If the method must
return multiple values, redesign it to return a single instance of an
object that holds the values.
If you are not able/willing to change the protection type or change the code to simply return the string, then you will have to ignore this fxcop rule . Which, is not a horrible thing. You have to decide which rules seem pertinent and which do not.
Your code would have to be something like GetAttributeValue, and use a check for null if you want to avoid this fxcop rule. Or, you could create a special class and use a Null object pattern, but that seems to be way too much overkill.
In the end, you are in control of your code, and not all rules are meant for everybody.
If you read the whole article, you can see at the end the following:
Methods that implement the Try pattern, such as
Int32.TryParse, do not raise this violation.
So as long as your methode return a bool and has a name like TryGetSomething, you are not violating the rule if you use the out parameter.

Method invocation with out parameter and no additional variable? [duplicate]

After reading on stackoverflow that in the case of checking the format of a DateTime you should use DateTime.TryParse. After trying some regex expressions they seem to get long and nasty looking to cover lots of the formatting.
But TryParse requires an "out" parameter and since I just want to do a validation format check I don't need the actual result.
So I am left with a variable that holds the "out" result and am to do nothing with it. Is there a way so I don't have to do a out parameter?
So I get rid of this warning and stop having a variable just flying around.
With C#7.0 (since August 2016) you can use the out var construct, and then just ignore the new var in subsequent code.
bool success = DateTime.TryParse(value, out var result);
If you truly do not care about the value of the result, use discards:
bool success = DateTime.TryParse(value, out _);
Nope. I'd wrap it in a method somewhere to keep the noise out of the main flow:
bool IsValidDate(string value)
{
DateTime result;
return DateTime.TryParse(value, out result); //result is stored, but you only care about the return value of TryParse()
}
I'm not suggesting you actually do this, but you could use a single helper class to make this easy for all out parameters:
public static class OutHelper<T>
{
[ThreadStatic]
public static T Ignored;
}
Then you can call:
if (DateTime.TryParse(text, out OutHelper<DateTime>.Ignored))
It's horrible, uses a public mutable field, and if your application is also executing with some malicious code, it gives that code access to the last value you've parsed... but it should work :)
No. You can't get rid of the variable but you shouldn't get a compiler warning either.
Passing a variable as out is "using" the variable. The compiler will not issue a warning because of that.
If you are using .NET 3 and above, you could always create an Extension method?
public static bool IsValidDate(this string value)
{
DateTime date = DateTime.Null;
return DateTime.TryParse(value, out date);
}
[Edited to rename the method name to a more appropriate one]
TryParse is a better option. Its just a variable that is wasted. Other options include using the Convert.ToDateTime() within a try-catch block. But again that would not be efficient because try-catch blocks are meant to be heavy. The next option is regex. This is a better solution. I guess this gives you the result instantly than compared to the others.
You can very well wrap the method like Kim Gräsman said...

Null out parameters in C#?

After reading on stackoverflow that in the case of checking the format of a DateTime you should use DateTime.TryParse. After trying some regex expressions they seem to get long and nasty looking to cover lots of the formatting.
But TryParse requires an "out" parameter and since I just want to do a validation format check I don't need the actual result.
So I am left with a variable that holds the "out" result and am to do nothing with it. Is there a way so I don't have to do a out parameter?
So I get rid of this warning and stop having a variable just flying around.
With C#7.0 (since August 2016) you can use the out var construct, and then just ignore the new var in subsequent code.
bool success = DateTime.TryParse(value, out var result);
If you truly do not care about the value of the result, use discards:
bool success = DateTime.TryParse(value, out _);
Nope. I'd wrap it in a method somewhere to keep the noise out of the main flow:
bool IsValidDate(string value)
{
DateTime result;
return DateTime.TryParse(value, out result); //result is stored, but you only care about the return value of TryParse()
}
I'm not suggesting you actually do this, but you could use a single helper class to make this easy for all out parameters:
public static class OutHelper<T>
{
[ThreadStatic]
public static T Ignored;
}
Then you can call:
if (DateTime.TryParse(text, out OutHelper<DateTime>.Ignored))
It's horrible, uses a public mutable field, and if your application is also executing with some malicious code, it gives that code access to the last value you've parsed... but it should work :)
No. You can't get rid of the variable but you shouldn't get a compiler warning either.
Passing a variable as out is "using" the variable. The compiler will not issue a warning because of that.
If you are using .NET 3 and above, you could always create an Extension method?
public static bool IsValidDate(this string value)
{
DateTime date = DateTime.Null;
return DateTime.TryParse(value, out date);
}
[Edited to rename the method name to a more appropriate one]
TryParse is a better option. Its just a variable that is wasted. Other options include using the Convert.ToDateTime() within a try-catch block. But again that would not be efficient because try-catch blocks are meant to be heavy. The next option is regex. This is a better solution. I guess this gives you the result instantly than compared to the others.
You can very well wrap the method like Kim Gräsman said...

Categories

Resources