How to apply Null-Conditional Operator on blank strings? - c#

I have a string value and need to convert that to decimal.
var str = null;
decimal number;
decimal d = Decimal.TryParse(str, out number) ? number : 0M;
It's working fine.
Now I am trying to achieve the same thing by using the new Null-Conditional Operator of C# 6.0 . How can I do so?
I know it's a wrong attempt.
var str = null;
decimal d = str?.Convert.ToDecimal(str);

A blank (empty) string is not null, so you can't use that operator.
You could do:
decimal d = string.IsNullOrEmpty(str) ? 0M : Convert.ToDecimal(str);
EDIT: OK, now we're starting with a null string. In which case...
decimal d = (str == null) ? 0M : Convert.ToDecimal(str);
I still don't think that this is an appropriate time to use the null-conditional operator, because that's most useful when the ultimate result of the expression can be null - which is not true in your case.

According to msdn you can't do that as null conditional operator is:
Used to test for null before performing a member access (?.) or index
(?[) operation
and in this case you aren't indexing or accessing the input string members.
As the other answer stated the way to do that would be
decimal d = String.IsNullOrEmpty(str) ? default(decimal) : Convert.ToDecimal(str);

Not exactly answering the question, but I would create an extension method where you have the advantage of being able to formally call it on null values too.
This implementation gives the correct double if the input string is in a valid format (using the default formatting), and gives the optionally passed default value if string is null or empty or is in incorrect format.
public static double ConvertToDoubleOrDefault(this string input, double def = 0.0)
{
if (string.IsNullOrEmpty(str)) return def;
double result;
if (!double.TryParse(str, out result)) return def;
return result;
}
....
string test = "1234";
string test2 = null;
var d = test.ConvertToDoubleOrDefault(); // => 1234
d = test2.ConvertToDoubleOrDefault(); // => 0.0

Related

Ignore dots in Convert.ToDecimal and return 0

I am using Convert.ToDecimal in linq, sometime amount value contains dot (.) as user want to write .50 or similar, as soon as they enter dot (using Numeric keypad from mobile), code is getting executed and throwing an exception.
I am getting string is not correct format exception for below code
var enteredAmountInTenders = TenderListCollection.Sum(x => Convert.ToDecimal(string.IsNullOrEmpty(x.Amount) ? "0" : x.Amount));
How can I ignore dot for above code and just get 0?
I would use decimal.TryParse instead of Convert.ToDecimal to cast the value.
var enteredAmountInTenders = TenderListCollection
.Sum(x => !decimal.TryParse(x.Amount,out var result) ? 0 : result);
you could check this before your set your property for the object in your TenderListCollection.
private string _amount = "0";
public string Amount
{
get
{
return _amount;
}
set
{
if(!string.IsNullOrEmpty(value))
{
if(value != ".")
{
_amount = value;
}
}
}
}
In general i dont like storing amounts as string, so i also would suggest to rename the Amount to GivenAmount and have an Amount Property which is a decimal, this way our code is clean and you dont need to parse in a Lambda expression.

Get string from array or set default value in a one liner

So we have ?? to parse its right-hand value for when the left hand is null.
What is the equivalent for a string[].
For example
string value = "One - Two"
string firstValue = value.Split('-')[0] ?? string.Empty;
string secondValue = value.Split('-')[1] ?? string.Empty;
Above example would still crash if we would try to get a third index or if string value = "One". Because it is not null but IndexOutOfRangeException is thrown.
https://learn.microsoft.com/en-us/dotnet/api/system.indexoutofrangeexception
So what is a one-line solution to tackle the above problem? I'd like to avoid the try-catch scenario because this gives ugly code.
I want to get value out of a string[] with a string.Empty as a backup value so my string is never null.
Well, you can try Linq:
using System.Linq;
...
string thirdValue = value.Split('-').ElementAtOrDefault(2) ?? string.Empty;
However, your code has a drawback: you constantly Split the same string. I suggest extracting value.Split('-'):
string value = "One - Two"
var items = value.Split('-');
string firstValue = items.ElementAtOrDefault(0) ?? string.Empty;
string secondValue = items.ElementAtOrDefault(1) ?? string.Empty;
I suggest you create a method for this. which will accept two inputs of type string(representing the input string) and an integer(represents the specified index), and should return the split value if the specified index is available, else it will return an empty string:
string GetSubstring(string input, int index)
{
string returnValue = String.Empty;
string[] substrings = input.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
returnValue = substrings.Length > index ? substrings[index] : returnValue;
return returnValue;
}
Here is a working example for your reference
One way to achieve this is to use MoreLinq's Lead and tuple destructuring:
string value = "One - Two";
var (first, second) = value.Split('-').Lead(1, string.Empty, (x, y) => (x, y)).First();
Or, if you want a more generic approach that works for all indices:
string value = "One - Two - Three - Fourth - Fifth";
var (first, second) = value.Split('-').Skip(6).Concat(string.Empty).Lead(7, string.Empty, (x, y) => (x, y)).First();
This code will get the seventh and fourteenth entries (neither of which are there, so string.Empty will be used for both).
Another option to consider is to assign two different variables on the same line of code:
string value = "One - Two";
var split = value.Split('-');
string first = split[0] ?? string.Empty, second = split.ElementAtOrDefault(1) ?? string.Empty;
This gives you three lines of code, good performance and reasonable level of clarity and readability.
Note there is no need to use ElementOrDefault(0) - better to use [0] since Split will never return an array with no elements in it.
Another option would be to use destructuring - but that is really only useful if you are interested in contiguous entries at the start of the array (although it could be tweaked to take index parameters reasonably simply):
public static void Destructure<T>(this T[] items, T defaultValue, out T t0, out T t1)
{
t0 = items.Length > 0 ? items[0] : defaultValue;
t1 = items.Length > 1 ? items[1] : defaultValue;
}
Maybe the following code will be useful
string value = "One - Two";
string firstValue = (value.Split('-').Length == 1 ? value.Split('-')[0] : null) ?? string.Empty;
string secondValue = (value.Split('-').Length == 2 ? value.Split('-')[1] : null) ?? string.Empty;

Get exponential value using regular expression

I have string like this:
strings s = "1.0E-20"
Is there a way to get only -20 from this using regex?
I tried this:
(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE][-+]?[0-9]+)?
this gets me e-20 in group5 but still not just -20.
Use Regex for dealing with text, use Math(s) for dealing with numbers:
Math.Log10(Convert.ToDouble("1.0E-20")) // returns -20
To make sure your string input is a valid double use TryParse:
double d, result = 0.0;
if (Double.TryParse("1.0E-20", out d))
{
result = Math.Log10(d);
}
else
{
// handle error
}
Also, if you want to get the 1.0 (multiplier) from your input:
var d = Convert.ToDouble("1.0E-20");
var exponent = Math.Log10(d);
var multiplier = d / exponent;
No need for Regex when string methods can do wonders
string str = "1.0E-20";
str = str.Substring(str.IndexOf('E') + 1);
You can do that without Regex like:
string s = "1.0E-20";
string newStr = s.Substring(s.IndexOf('E') + 1);
Later you can parse the string to number like:
int number;
if (!int.TryParse(newStr, out number))
{
//invalid number
}
Console.WriteLine(number);
You can also use string.Split like:
string numberString = s.Split('E')[1]; //gives "-20"
Its better if you add check for string/array length when access string.Substring or accessing element 1 after split.
var x = str.IndexOf("E") != -1 ? str.Substring(str.IndexOf("E") + 1) : "1";
If you want to use regular expressions to achieve this, you should switch up your capture groups.
(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE])([-+]?[0-9]+)?
Group 6 will contain -20 with your given example with the regular expression above. Note how the parentheses have moved. We might need more information from you though. Do you have any more sample data? What's the end goal here?

Convert from string to int in c# Using Convert.ToInt32

I have a simple code in c# that converts a string into int
int i = Convert.ToInt32(aTestRecord.aMecProp);
aTestRecord.aMecProp is of string. The test I am running, during that it has values of 1.15 in string.
but above line throws error saying that input string wasn't in a format!
I don't understand why?
I am using VS 2008 c#
An integer can only represent strings without a decimal part.
1.15 contains a decimal part of 0.15.
You have to convert it into a float to keep the decimal part and correctly parse it:
float f = Convert.ToSingle(aTestRecord.aMecProp);
That is because 1.xx is not a integer valid value. You could truncate before converting to Int32, for sample:
int result = (int)(Math.Truncate(double.Parse(aTestRecord.aMecProp)* value) / 100);
if you are trying to validate that a string is an integer, use TryParse()
int i;
if (int.TryParse(aTestRecord.aMecProp, out i))
{
}
i will get assigned if TryParse() is successful
Try this:
double i = Convert.ToDouble(aTestRecord.aMecProp);
Or if you want the integer part:
int i = (int) Convert.Double(aTestRecord.aMecProp);
You can convert to double and then typecast it
string str = "1.15";
int val = (int)Convert.ToDouble(str);
Just try this,
Int32 result =0;
Int32.TryParse(aTestRecord.aMecProp, out result);
Do you need a C# equivalent for the JavaScript parseInt function? I have used this one on occasion:
public int? ParseInt(string value)
{
// Match any digits at the beginning of the string with an optional
// character for the sign value.
var match = Regex.Match(value, #"^-?\d+");
if(match.Success)
return Convert.ToInt32(match.Value);
else
return null; // Because C# does not have NaN
}
...
var int1 = ParseInt("1.15"); // returns 1
var int2 = ParseInt("123abc456"); // returns 123
var int3 = ParseInt("abc"); // returns null
var int4 = ParseInt("123"); // returns 123
var int5 = ParseInt("-1.15"); // returns -1
var int6 = ParseInt("abc123"); // returns null
ok I think this is
float d = Convert.ToSingle(aTestRecord.aMecProp);

how to do this conversion?

string mvi = Moneys.GetValue(8) as string;
if (mvi == null)
// I am getting exception Here if its null?
money.Currency= Convert.ToDecimal("");
else
// Currency is Decimal
money.Currency= Convert.ToDecimal(mvi);
// I am getting exception Here if its null?
money.Currency= Convert.ToDecimal("");
Can anybody tell me how to do this?
Empty string is not convertible to decimal. You could perform a check like this
if (string.IsNullOrEmpty(mvi))
{
money.Currency = 0M;
}
else
{
decimal temp = 0M;
if (decimal.TryParse(mvi, out temp))
{
money.Currency = temp;
}
else
{
// you have an invalid input, handle
}
}
Here's my version of Anthony Pegram's answer:
string mvi = Moneys.GetValue(8) as string;
money.Currency = 0M;
if (!String.IsNullOrEmpty(mvi))
if (!Decimal.TryParse(mvi, out money.Currency))
throw new FormatException("mvi");
On the whole, it looks quite a bit like the one Alex made, only it treats empty as zero and shows more error-handling.
You can use TryParse instead of Convert.ToDecimal():
decimal theValue;
string mvi = Moneys.GetValue(8) as string;
Decimal.TryParse( mvi, out theValue );
alternatively, you can use the null coallescing operator to handle nulls preemtively:
var theValue = Convert.ToDecimal( mvi ?? "0" );
In both cases, however, you have to decide what to do if the value coming in is not a valid decimal.
http://msdn.microsoft.com/en-us/library/hf9z3s65.aspx
I think you want Convert.ToDecimal("0.0"); otherwise you get a EDIT: ArgumentNullException

Categories