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...
Related
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.
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.
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...
I have a function that returns a modified copy of the object that was passed to this function. I often do something like this:
obj = obj.Foo(param);
Don't ask why, I simply have to. But sometimes, I (and others) forgot to assign the return value, doing this:
obj.Foo(param);
which repeatedly leads to time-consuming debugging.
Is there any way to show a warning or error every time when the function result is not assigned to a variable? Or any other suggestions on how to solve this issue?
You could use an out parameter, so the call would look like this:
obj.Foo(param, out obj);
You can use Resharper to assist with this issue; you need to decorate your method with the [Pure] attribute:
[Pure]
public static IList<T> RemoveItem<T>(this IEnumerable<T> thisList, T item)
{
var list = thisList.ToList();
list.Remove(item);
return list;
}
then when you call it without assigning the return value you will see:
The [Pure] attribute is defined in Resharpers Data Annotations: You need to copy the classes into your project so you can reference them (many very useful other annotations too)
It's totally legal and often desirable to not assign the return parameter so it would be wrong to have a warning for it. Henrik's answer to use an out parameter is what I'd recommend too to ensure the result is assigned everytime.
you can enable visual studio warings.
you can even customize the rule you want to apply.
you should see warnings in the case you don't assign the function to a variable
you can also decide to treat the waring as errors
Example:
public static class MyClass
{
public static string GetStr()
{
return "";
}
public static void Main()
{
GetStr();
}
}
I can't comment on answers, lacking stackoverflow credits. But I agree with Chris that it's totally legal and often desirable not to assign values returned from a method. It's also occasionally not desirable. e.g.
public static int Square(this int myValue)
{
return myValue * myValue;
}
It's clear that calling this method without assigning it is probably a bug. I think creating a code analysis rule that warned every time you didn't assign a value as Massimiliano suggested would be worse than not having the rule at all. In such cases it would be nice to be able to apply an attribute to the method...
[MustAssign]
public static int Square...
You could create a rule as Massimiliano suggested but only invoke the warning when the method is adorned with the attribute and the value returned from the method is not assigned. Not a trivial exercise though.
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