Change this condition so that it does not always evaluate to 'true' - c#

Why is SonarQube complaining about this part of the code?
I checked this code and not always this value is true.
public static void WriteJson(object value)
{
decimal decimalValue = ((decimal?)value).Value;
int intValue = (int)decimalValue;
if (decimalValue == intValue)
Console.WriteLine(intValue);
else
Console.WriteLine(decimalValue);
Console.ReadKey();
}
Why is SonarQube complaining about this?

The false positive is related to an imperfection in our dataflow analysis engine - it does not take into account the casts between floating point and integer numbers (yet) and cannot recognize when a floating point number has been truncated.
I will try to elaborate a bit: the dataflow analysis engine tracks the values of the local variables in the analyzed methods, and when a new value is being assigned to a variable, the engine creates a special object that represents the actual value. When you assign one variable to another variable, that object remains the same. For example:
var x = 5; // the symbol of x is associated with value_0
var y = x; // the symbol of y is associated with value_0
if (x == y) // value_0 is compared with value_0 --> always true
The values we assign do not contain type information (yet) and we cannot detect (yet) changes in cases like yours:
var x = 5.5; // the symbol of x is associated with value_0
var y = (int)x; // the symbol of y is associated with value_0 (wrong)
if (x == y) // false positive
and we generate false positives, but they are relatively rare, because most casts do not generate new values.
Thanks for the feedback, we will be looking into that in the near future.

Looks like SonarQube detects that you are assigning the same value to both variables, assume that value passed to method is equal to 2
1. decimal decimalValue = 2
2. int intValue = (int)decimalValue;
therefore decimalValue = 2 and intValue = 2
The C# compiler will obviously cast it to int so in case you pass 2.5 the if comparision will not evaluate always to true. But most probably SonarQube is just not aware about the casting. So it assumes always true.

I am not an expert at SonarQube, but I guess it is because SonarQube detects that you are setting intValue to the rounded form of decimalValue. And then again you are comparing decimalValue to the decimal form of intValue. So, in many cases, it will return 'true'.
To see how it will play out, suppose the decimalValue is "123.0". Then, the intValue will be exactly "123". Then, we compare "123.0"(The value of decimalValue) to "123.0"(The value of intValue after converting to decimal) with an "if" statement, which will return true. This will play out for all integers.

Related

C# What does int i = +1 mean?

I was browsing around stack overflow and I encountered this question:
check for duplicate filename when copying files in C#
In this question, this little gem existed:
int i = +1
I have never seen this syntax before. So I opened up the interactive C# window in visual studio:
Microsoft (R) Roslyn C# Compiler version 1.3.4.60902
Loading context from 'CSharpInteractive.rsp'.
Type "#help" for more information.
> int i = +1;
> i
1
> +1 == 1
true
Is this similar to +=? Is this some new syntax? What is this operator? How is it different than a normal variable declaration?
That's the unary plus operator. From the documentation:
The result of a unary + operation on a numeric type is just the value of the operand.
In most sane contexts1 where you're writing code, it'll be optional (+1 is the same as 1 if we're writing literals).
It mostly exists for symmetry with the unary minus operator.
Most of the time, you'll not write code containing it, but if you're generating code it can be handy to be able to apply a unary operator either way2.
It has no relation to +=.
1Insane code could override this operator for custom types and make it more than a no-op. But I'd love to understand a use case where it makes code more understandable, which should be the main aim of most code.
2E.g. imagine you're chaining a set of operations together and for each additional element, you wish to change the sign of the overall result. This lets you just store an operator and apply it blindly when you finally decide to output a result
For for all signed numeric types the positive-sign is optional. So,
+1 == (+1) == 1
+1.0 == (+1.0) == 1.0
+1L == (+1L) == 1L
+1.0m == (+1.0m) == 1.0m
Do not confuse
int i = +1; // Assigns 1
which is the same as
int i = (+1); // Assigns 1
or simply
int i = 1; // Assigns 1
with
int i += 1; // INCREMENT!
which increments i.
In C# terms there is a binary + operator (the addition operator as in int i = 3 + 4;) and a unary + operator (the plus sign as in int i = +1;).
Think of it the way you think of
int i = -1
and it becomes obvious

C# ignore empty textboxes

I have ha a WinForms app with some textboxes.
At the moment the app is simple and i only want to test how it will work.
It will get mutch more complex in the future.
What i tried to do create a rule to ignore empty textboxes or if empty use the value 0.
The code i have is this one:
decimal ata;
decimal a1;
decimal a2;
decimal a3;
decimal a4;
decimal a5;
decimal j = 0;
a1 = decimal.TryParse(textBox1.Text, out j);
a2 = decimal.Parse(textBox2.Text);
a3 = decimal.Parse(textBox4.Text);
a4 = decimal.Parse(textBox10.Text);
a5 = decimal.Parse(textBox24.Text);
ata = a1 + a2 + a3 + a4 + a5;
resposta.Text = ata.ToString();
i get an error "Cannot implicitly convert type 'bool' to 'decimal'
in the line:
a1 = decimal.TryParse(textBox1.Text, out j);
Can anyone help me with this problem.
Thanks in advance,
Use decimal.TryParse(textBox1.Text, out j); instead of a1 = decimal.TryParse(textBox1.Text, out j);. Your value is returned in j
You declared
decimal a1;
Then you tried:
a1 = decimal.TryParse(textBox1.Text, out j);
decimal.TryParse returns a bool not a decimal
j
Is taking the parsed value
The TryParse method returns a bool value to indicate whether conversion succeeded or not. The real value is returned in the second parameter (out parameter).
You could try:
if (Decimal.TryParse(textBox1.Text, out j))
a1 = j;
This only sets a1 if parsing was successful. Otherwise a1 keeps its previous value.
The way you want to use the TryParse() method is like so
decimal a1 = 0;
bool parsed = decimal.TryParse(textBox1.Text, out a1);
if(parsed)
{
//your arithmetic
}
else
{
//throw error
}
The error is because TryParse() returns a boolean, not a decimal. You need to write explicit if statements to test if the textboxes are empty. You should consider wrapping this in a method.
You are trying to assign a bool value to a decimal variable that's why getting this error.
Decimal.TryParse() will return bool value, Please take a look here you can use this value to check parsing is successful or not.
You will get result in your out parameter i.e j.
the return value TryParse is a bool. It indicates whether the conversion was successful or not. Usually you would use it like this:
decimal j;
if (decimal.TryParse(textBox1.Text, out j))
{
// here the conversion worked and it is save to use j
}
You check whether it was successful and in this case you can use the value of the converted variable, otherwise it will remain null.
Here is the documentation
In respect to the value that is passed via the out keyword the documentation says: (s is equivalent to textBox1.Text and result is equivalent to j)
When this method returns, result contains the Decimal number that is equivalent to the numeric value contained in s, if the conversion succeeded, or is zero if the conversion failed. The conversion fails if the s parameter is null or String.Empty, is not a number in a valid format, or represents a number less than MinValue or greater than MaxValue. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.
One of the nice things of object oriented programming is reusability of code in similar situations.
You mentioned you are going to use some kind of "nullable decimal text boxes" a lot of times. Why not create a class for it? You'll only have to create the class once, and everyone who needs your nullable decimal text box (especially you with all your text boxes) can reuse this one code.
Bonus: if you ever need to change the behaviour of this kind of text boxes, for instance get a yellow background when empty, all your special text boxes instantaneously behave the same.
To make it possible to ignore empty text boxes you need a property IsEmpty
Property Value returns the Value of the text box as a decimal or 0M if IsEmpty
What do you want to return if not empty but text is not a decimal?
public class MyNullableTextBox : TextBox
{
public bool IsEmpty {get{return String.IsNullOrEmpty(base.Text);} }
public decimal Value
{
get
{
if (this.IsEmpty)
return 0M;
else
{
decimal parsedValue;
bool parsed = Decimal.TryParse(base.Text, out parsedValue);
if (!parsed)
// decide what you want in this case
else
return parsedValue;
}
}
}
}
The nice thing is, that once you've added this (as a reference) to your solution, it can be found in the Toolbox and used in your forms designer as if it was a regular text box

Compare two integer objects for equality regardless of type

I'm wondering how you could compare two boxed integers (either can be signed or unsigned) to each other for equality.
For instance, take a look at this scenario:
// case #1
object int1 = (int)50505;
object int2 = (int)50505;
bool success12 = int1.Equals(int2); // this is true. (pass)
// case #2
int int3 = (int)50505;
ushort int4 = (ushort)50505;
bool success34 = int3.Equals(int4); // this is also true. (pass)
// case #3
object int5 = (int)50505;
object int6 = (ushort)50505;
bool success56 = int5.Equals(int6); // this is false. (fail)
I'm stumped on how to reliably compare boxed integer types this way. I won't know what they are until runtime, and I can't just cast them both to long, because one could be a ulong. I also can't just convert them both to ulong because one could be negative.
The best idea I could come up with is to just trial-and-error-cast until I can find a common type or can rule out that they're not equal, which isn't an ideal solution.
In case 2, you actually end up calling int.Equals(int), because ushort is implicitly convertible to int. This overload resolution is performed at compile-time. It's not available in case 3 because the compiler only knows the type of int5 and int6 as object, so it calls object.Equals(object)... and it's natural that object.Equals will return false if the types of the two objects are different.
You could use dynamic typing to perform the same sort of overload resolution at execution time - but you'd still have a problem if you tried something like:
dynamic x = 10;
dynamic y = (long) 10;
Console.WriteLine(x.Equals(y)); // False
Here there's no overload that will handle long, so it will call the normal object.Equals.
One option is to convert the values to decimal:
object x = (int) 10;
object y = (long) 10;
decimal xd = Convert.ToDecimal(x);
decimal yd = Convert.ToDecimal(y);
Console.WriteLine(xd == yd);
This will handle comparing ulong with long as well.
I've chosen decimal as it can exactly represent every value of every primitive integer type.
Integer is a value type. When you compare two integers types, compiller checks their values.
Object is a reference type. When you compare two objects, compiller checks their references.
The interesting part is here:
object int5 = (int)50505;
Compiller perfoms boxing operation, wraps value type into reference type, and Equals will compare references, not values.

C# equivalent to JavaScript "OR assignment"

Does C# have an equivalent to JavaScript's assignment syntax var x = y || z;? In case you don't know, the result is not true/false. If y is defined, then it is assigned to x, otherwise z is assigned to x even if it is undefined.
Note that in JavaScript the variable still has to be declared: var test;
I think that you are looking for ?? operator.
MSDN Reference
var abc = blah ?? "default";
yep
This is what you are looking for
var x = y ?? z;
In C# there's no such notion as variable not being defined. Such operator doesn't make sense in C#.
Unlike JavaScript, C# is not dynamic but static language so that such operation is impossible - a compilation error will occur.
Imagine you're writing this if:
if(pizzaPrice == hamburgerPrice)
Before declaring the variables first:
decimal pizzaPrice;
decimal hamburgerPrice;
An error will occur on compile-time.
Update:
Even if the variables were declared it doesn't matter because C# does not support such a feature.
On the other hand, JavaScript is enforcing evaluation of the variable in if conditions by calling the ToBoolean method and if it's undefined or null it's equals to false and C# doesn't not contains such a behavior.
Look at this cool article: JavaScript pitfalls: null, false, undefined, NaN
But if you want to check if a variable is referencing to a null you can easily use the null coalescing operator "??" operator.
As the following:
var x = y ?? z;
Yes, there is: ??
string x = y ?? z;
Which basically calculates:
string x = y != null ? y : z
However, there are a few differences between Javascript and C#. As with JS, y and z must both be declared before hand. However, unlike JS, y and z must also be "assigned" in C# or a compiler error will be thrown as usual.
The operator requires a nullable type and it checks whether the first is null before returning the second. You can chain a whole bunch (a ?? b ?? c ?? d ?? e) if you want.
Note that a zero length string is not null.

Nullable double NaN comparison in C#

I have 2 nullable doubles, an expected value and an actual value (let's call them value and valueExpected). A percentage is found using 100 * (value / valueExpected). However, if valueExpected is zero, it returns NaN. Everything good so far.
Now, what do I do if I need to check the value, to see if it is NaN? Normally one could use:
if (!Double.IsNaN(myDouble))
But this doesn't work with nullable values (IsNaN only works with non-nullable variables). I have changed my code to do the check (valueExpected == 0), but I'm still curious - is there any way to check for a nullable NaN?
Edit: When I say the code doesn't work, I mean it won't compile. Testing for null first doesn't work.
With all Nullable<T> instances, you first check the bool HasValue property, and then you can access the T Value property.
double? d = 0.0; // Shorthand for Nullable<double>
if (d.HasValue && !Double.IsNaN(d.Value)) {
double val = d.Value;
// val is a non-null, non-NaN double.
}
You can also use
if (!Double.IsNaN(myDouble ?? 0.0))
The value in the inner-most parenthesis is either the myDouble (with its Nullable<> wrapping removed) if that is non-null, or just 0.0 if myDouble is null. Se ?? Operator (C#).
I had the same issue and I solved it with casting the double? with double
double.IsNaN((double)myDouble)
this will return true if NaN and false if not
With C# 7.0 Pattern matching combined null + NaN check check can be written like this:
double? d = whatever;
if(d is double val && double.IsNaN(val))
Console.WriteLine(val);
The advantage is local scoped variable val at hand, which is not null, nor double.NaN and can even be used outside of if.
With pattern matching in newer Roslyn C# versions, double.NaN is a valid pattern which tests using IsNaN (that is it works differently than Equals() where NaN is never equal to NaN as specified by IEEE floating point standard).
Therefore you can now do this:
double? myDouble = something;
if (myDouble is double and not double.NaN)
Console.WriteLine("A number");
For testing NaN this can even be shortened like this:
double? myDouble = something;
if (myDouble is double.NaN)
Console.WriteLine("Not a number and not NULL");

Categories

Resources