Cast string to decimal? (nullable decimal) by extension method - c#

I want to cast a string to a decimal?. With reference to a previous question here
one of the answers gave a object extension to convert objects like so
public static class ObjectExtensions
{
public static Nullable<T> ToNullable<T>(this object input)
where T : struct
{
if (input == null)
return null;
if (input is Nullable<T> || input is T)
return (Nullable<T>)input;
throw new InvalidCastException();
}
}
usage :
object value = 123.45m;
decimal? dec = value.ToNullable<decimal>();
The above does not work with string however, is it possible to define a companion to the above method to specifically handle strings?
specifically like what I would like to be able to do is :-
object v1 = 123.45m;
decimal? d1 = v1.ToNullable<decimal>();
object v2 = "123.45";
decimal? d2 = v2.ToNullable<decimal>();

A simple extension method converts string to decimal. For not null strings of course
public static class StringExtensions
{
public static decimal? ToNullableDecimal(this string s)
{
decimal value;
if (!Decimal.TryParse(s, out value)
return null;
return value;
}
}

Given your extension function, why not something like :
public static class ObjectExtensions
{
public static Nullable<T> ToNullable<T>(this object input)
where T : struct
{
if (input == null)
return null;
if (input is Nullable<T> || input is T)
return (Nullable<T>)input;
else if (input is string)
return (T)Convert.ChangeType(input, typeof(T));
throw new InvalidCastException();
}
}
It will work for numeric types (supported by ChangeType), and even Dates and so.
Of course, "input" must be convertible to desired type (beware of culture-specific constraints).
To improve this, you could pass to "ChangeType" (at third parameter) the Culture you want to work with, for example return ((T)Convert.ChangeType(input, typeof(T), new CultureInfo("en-US")));
You can also add stuff in this method to handle exceptions, etc

You could do something like this:
string nds = null;
decimal? d = (nds != null) ? Convert.ToDecimal(nds) : default(decimal?);

Here is what is work for me
1- Create following method inside a class (ex ValidationHelper)
public static decimal? Todecimal(string s,decimal defValue=0)
{
if (s.Trim()!="")
{
return Convert.ToDecimal(s);
}
else
{
return defValue;
}
}
and then you can use it anywhere in your app like this
prod.Qty = ValidationHelper.Todecimal(txtQty.Text,1);//ex: assuming the default value for Qty is 1.
Hope this will help someone. Thanks

Related

C# - Receive string and use it as an enum key [duplicate]

I have an enum type like this as an example:
public Enum MyEnum {
enum1, enum2, enum3 };
I'll read a string from config file. What I need is to parse the string to MyEnum type or null or not defined. Not sure if the following code will work (sorry for not having access to my VS right now):
// example: ParseEnum<MyEnum>("ENUM1", ref eVal);
bool ParseEnum<T>(string value1, ref eVal) where T : Enum
{
bool bRet = false;
var x = from x in Enum.GetNames(typeof(T)) where
string.Equals(value1, x, StringComparison. OrdinalIgnoreCase)
select x;
if (x.Count() == 1 )
{
eVal = Enum.Parse(typeof(T), x.Item(0)) as T;
bRet = true;
}
return bRet;
}
Not sure if it is correct or there is any other simple way to parse a string to a MyEnum value?
What about something like:
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
if (!string.IsNullOrEmpty(input))
{
if (Enum.GetNames(typeof(T)).Any(
e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant()))
{
return (T)Enum.Parse(typeof(T), input, true);
}
}
return null;
}
}
Used as:
MyEnum? value = EnumUtils.Parse<MyEnum>("foo");
(Note: old version used try/catch around Enum.Parse)
private enum MyEnum
{
Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6,
Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10
}
private static Object ParseEnum<T>(string s)
{
try
{
var o = Enum.Parse(typeof (T), s);
return (T)o;
}
catch(ArgumentException)
{
return null;
}
}
static void Main(string[] args)
{
Console.WriteLine(ParseEnum<MyEnum>("Enum11"));
Console.WriteLine(ParseEnum<MyEnum>("Enum1"));
Console.WriteLine(ParseEnum<MyEnum>("Enum6").GetType());
Console.WriteLine(ParseEnum<MyEnum>("Enum10"));
}
OUTPUT:
//This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .
This is an old question, but now .NET 4.5 has Enum.TryParse<TEnum>().
I have a TryParseName method in UnconstrainedMelody, a library for delegate and enum utility methods which uses "inexpressible" constraints via some postbuild trickery. (Code using the library doesn't need a postbuild, just to be clear.)
You would use it like this:
Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);
I don't currently have a case-insensitive version, but I could easily introduce one if you wanted. Note that this doesn't try to parse numbers e.g. "12" like the built-in version does, nor does it try to parse comma-separated lists of flags. I may add the flags version later on, but I can't see much point in the numeric version.
This is done without boxing and without execution time type checking. Having the constraint is really handy :)
Please let me know if you'd find a case-insensitive parse useful...
If you're using .NET 3.5 (or even 2.0, if you trim out the extension method), I've had great luck with the techniques in this article:
Enumerations and Strings - Stop the Madness!
EDIT: Domain is gone and is now a link farm. I pulled the code (slightly modified and added to over time) from our codebase at work, which you can now find here:
https://gist.github.com/1305566
You can use TryParse if you want to avoid using try/catch.
MyEnum eVal;
if (Enum.TryParse("ENUM2", true, out eVal)){
// now eVal is the enumeration element: enum2
}
//unable to parse. You can log the error, exit, redirect, etc...
I modified the selected answer a little bit. I hope you like it.
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
int intVal;
if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal))
{
T eVal;
if (Enum.TryParse(input, true, out eVal))
{
return eVal;
}
}
return null;
}
}
I have just combined the syntax from here, with the exception handling from here, to create this:
public static class Enum<T>
{
public static T Parse(string value)
{
//Null check
if(value == null) throw new ArgumentNullException("value");
//Empty string check
value = value.Trim();
if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
//Not enum check
Type t = typeof(T);
if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum");
return (T)Enum.Parse(typeof(T), value);
}
}
You could twiddle it a bit to return null instead of throwing exceptions.
To return Enum by string, if contains:
public static T GetEnum<T>(string s)
{
Array arr = Enum.GetValues(typeof(T));
foreach (var x in arr)
{
if (x.ToString().Contains(s))
return (T)x;
}
return default(T);
}

Elegant TryParse

I feel that every time I use TryParse that it results in somewhat ugly code. Mainly I am using it this way:
int value;
if (!int.TryParse(someStringValue, out value))
{
value = 0;
}
Is there some more elegant solution for parsing all basic data types, to be specific is there a way to do fail safe parsing in one line? By fail safe I assume setting default value if parsing fails without exception.
By the way, this is for cases where I must do some action even if parsing fails, just using the default value.
This is valid and you may prefer it if you have a liking for single-liners:
int i = int.TryParse(s, out i) ? i : 42;
This sets the value of i to 42 if it cannot parse the string s, otherwise it sets i = i.
how about a direct extension method?
public static class Extensions
{
public static int? TryParse(this string Source)
{
int result;
if (int.TryParse(Source, out result))
return result;
else
return null;
}
}
or with the new c# syntax in a single line:
public static int? TryParse(this string Source) => int.TryParse(Source, out int result) ? result : (int?)null;
usage:
v = "234".TryParse() ?? 0
You can write your own methods for a solution that suits you better. I stumbled upon the Maybe class that wraps the TryParse methods a while ago.
int? value = Maybe.ToInt("123");
if (value == null)
{
// not a number
}
else
{
// use value.Value
}
or specify the default value in-line:
int value = Maybe.ToInt("123") ?? 0;
Observe the distinction between Nullable<int>/int? and int.
See http://www.kodefuguru.com/post/2010/06/24/TryParse-vs-Convert.aspx for more info
There is a nice little feature in C# 6 C# 7, Declaration expressions, so in C# 7 instead of:
int x;
if (int.TryParse("123", out x))
{
DoSomethingWithX(x);
}
we can use:
if (int.TryParse("123", out int x))
{
DoSomethingWithX(x);
}
Nice enough for me :)
using C# 7 in single line
int.TryParse(s, out var i) ? i : (int?)null;
Example Method:
public static int? TryParseSafe(string s)
{
return int.TryParse(s, out var i) ? i : (int?)null;
}
In your particular example, you can do this:
int value;
int.TryParse(someStringValue, out value);
...because Int32.TryParse() is documented as setting value=0 if it fails the parse.
You could use TypeDescriptor instead:
public T Convert<T>(string input, T defaultVal)
{
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
if(converter != null)
{
return (T)converter.ConvertFromString(input);
}
return defaultVal;
}
public T Convert<T>(string input)
{
return Convert(input, default(T));
}
You could constrain T to struct and use Nullable also (as per #skarmats answer).
This is one of the nice surprises for C# developers who try F#.
The TryParse method returns a tuple containing both the bool and the value.

How to write generic extension methods?

I am developing a generic wrapper around TryParse, as follows:
public delegate bool ParseDelegate<T>(string s, out T result);
public static T? ParseOrNull<T>(this string value, ParseDelegate<T> parse) where T : struct
{
T result;
var parsed = parse(value, out result);
return parsed ? result : (T?)null;
}
[Test]
public void ParsesValidInt()
{
Assert.AreEqual(1234, "1234".ParseOrNull<int>(int.TryParse));
}
[Test]
public void ParsesValidDecimal()
{
Assert.AreEqual(12.34M, "12.34".ParseOrNull<decimal>(decimal.TryParse));
}
This is kinda repetitive. Is there a way to avoid mentioning int.TryParse at all, so that my calls look as follows:
"1234".ParseOrNull<int>()
Is there a way to avoid mentioning int.TryParse at all, so that my calls look as follows:
Not directly, as TryParse isn't part of a shared interface. If there were a shared interface to these value types, this would be possible via a constraint.
Personally, I would not suggest using extension methods for this. I would rather write this as something more like:
public static class Parse
{
public delegate bool ParseDelegate<T>(string s, out T result);
public static T? FromString<T>(string value, ParseDelegate<T> parse) where T : struct
{
T result;
var parsed = parse(value, out result);
return parsed ? result : (T?)null;
}
public static int? ToNullableInt32(string value)
{
return FromString<int>(value, int.TryParse);
}
public static double? ToNullableDouble(string value)
{
return FromString<double>(value, double.TryParse);
}
}
This adds a bit of overhead up front, but allows you to write these very cleanly, ie:
int? first = Parse.FromString<int>("1234", int.TryParse);
int? second = Parse.ToNullableInt32("1234");
double? third = Parse.ToNullableDouble("1234");
I see little value in putting an extension method, especially on something like string (which is used everywhere), as it "pollutes" the compilation of string itself. You'll see this everywhere you use strings - basically, any time you use this namespace, you'll end up having these parse methods in your intellisense, etc. In addition, this seems more like a "utility" than something that should appear as built-in functionality of string itself, which is why I personally prefer a separate class for it.
In short no but you can add a new helper method:
public static int? ParseInt(this string value)
{
return value.ParseOrNull<int>(int.TryParse);
}
and then:
"1234".ParseInt();
Look at how Microsoft deals with several types . They provides one method for each type. Enumerable.Sum Method is a good example. If you want to simplify the calling code, you should provide the overloads for each types :
public static int? ParseOrNull<int>(this string value)
{
int result;
var parsed = int.TryParse(value, out result);
return parsed ? result : (T?)null;
}
public static long? ParseOrNull<long>(this string value)
{
long result;
var parsed = long.TryParse(value, out result);
return parsed ? result : (T?)null;
}
// same for ulong, long, uint, ushort, short, byte,
// bool, float, double, decimal. Do I forget one ?
I think it's more important to simplify calls than the method itself. In fact, there is not a huge number of types to deal with.
Yes, you can use Convert.ChangeType
public static T? ParseOrNull<T>(this string value) where T : struct, IConvertible
{
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch (FormatException ex)
{
return null;
}
}
It wont have as good performance (use of try catch) as TryParse, but should work for all IConvertible types
The answer is a big YES. You're trying to exploit the existence of the static T.TryParse(string, out T) function on the types you're converting to, and we can do that pretty easily with a little reflection.
public static T? ParseOrNull<T>(this string str)
where T: struct, IConvertible
{
// find the TryParse method.
var parseMethod = typeof(T).GetMethod("TryParse",
// We want the public static one
BindingFlags.Public | BindingFlags.Static,
Type.DefaultBinder,
// where the arguments are (string, out T)
new[] { typeof(string), typeof(T).MakeByRefType() },
null);
if (parseMethod == null)
// You need to know this so you can parse manually
throw new InvalidOperationException(
string.Format("{0} doesn't have a TryParse(..) function!",
typeof(T).FullName));
// create the parameter list for the function call
var args = new object[] { str, default(T) };
// and then call the function.
if ( (bool)parseMethod.Invoke(null, args))
return (T?)args[1]; // if it returned true
// if it returned false
return null;
}
This is the original answer I provided, based on the idea that you need two different parse methods: One for value types and another for reference types.
public delegate bool ParseDelegate<T>(string s, out T result);
public static T? ParseOrNull<T>(this string str, ParseDelegate<T> Parse)
where T: struct
{
T result;
if (!Parse(str, out result))
return null;
return result;
}
public static T ParseOrNull<T>(this string str, ParseDelegate<T> Parse)
where T : class
{
T result;
if (!Parse(str, out result))
return null;
return result;
}
public static T? ParseOrNull<T>(this string value)
where T : struct
{
T result = default(T);
object[] parameters = new object[] { value, result };
foreach (System.Reflection.MethodInfo method in
typeof(T).GetMethods()
.Where(method => method.Name == "TryParse")
.Where(method => method.GetParameters().Length == 2) //as opposed to the 4 argument version
.Take(1) //shouldn't be needed, but just in case
)
{
method.Invoke(null, parameters);
}
return (T)parameters[1];
}
As Reed mentions, I'd rather not use an extension method of string. I'd just use Parser.Parse(string value). Easy fix though, just remove the 'this' and voila.

How to use Double? nullable type with Math.Round in .NET

I want to do something like this but C# doesn't accept this:
public static void setPrice(Double? value)
{
if (value != null) {
this.TextBoxPrice.Text = Math.Round(value, 2).ToString();
} else {
this.TextBoxPrice.Text = "No Price";
}
}
So does it mean using nullable type Double? is completely useless in this use case ? What can I use then ?
Update: I made a mystypo I actually meant
public static void setPrice(Double? value)
so I corrected.
You're not currently using a nullable type - Double is a non-nullable value type, so can never be null. This is what you want:
public static void setPrice(Double? value)
{
if (value != null) {
this.TextBoxPrice.Text = Math.Round(value.Value, 2).ToString();
} else {
this.TextBoxPrice.Text = "No Price";
}
}
On the other hand, you should not be using a double to represent financial values. It's inappropriate as a binary floating point type. Use decimal (or decimal?) instead.
(Note that Double? is equivalent to Nullable<Double>.)
If you've come from a Java background, you may be expecting Double to be a reference "wrapper" type to start with - it's not. In C# double is simply an alias for System.Double; they're the same type.
Jon's answer is fine -- pay particular attention to the bit about decimal -- but I thought I'd add that you can "lift" methods to nullable using higher-order programming. For example:
public static Func<T?, T?> Lift<T>(Func<T, T> func) where T : struct
{
return (T? t)=>t.HasValue ? (T?)func(t.Value) : (T?)null;
}
public static Func<A?, R> LiftRef<A, R>(Func<A, R> func) where A : struct where R : class
{
return (A? a)=>a.HasValue ? func(a.Value) : null;
}
And now you can say:
Func<decimal, decimal> round2 = x=>Math.Round(x, 2);
Func<decimal?, decimal?> liftedRound2 = Lift(round2);
Func<decimal?, string> liftedToString = LiftRef(decimal.ToString);
...
public static void SetPrice(decimal? value)
{
this.TextBoxPrice.Text == liftedToString(liftedRound2(value)) ?? "No Price";
}
I agree with Jon Skeet's answer and just wanted to add that in that specific case you might consider simply adding a ClearPrice method - for reasons of clearer API + avoiding the if-else.

Best way to test if a generic type is a string? (C#)

I have a generic class that should allow any type, primitive or otherwise. The only problem with this is using default(T). When you call default on a value type or a string, it initializes it to a reasonable value (such as empty string). When you call default(T) on an object, it returns null. For various reasons we need to ensure that if it is not a primitive type, then we will have a default instance of the type, not null. Here is attempt 1:
T createDefault()
{
if(typeof(T).IsValueType)
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
Problem - string is not a value type, but it does not have a parameterless constructor. So, the current solution is:
T createDefault()
{
if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
But this feels like a kludge. Is there a nicer way to handle the string case?
Keep in mind that default(string) is null, not string.Empty. You may want a special case in your code:
if (typeof(T) == typeof(String)) return (T)(object)String.Empty;
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
Untested, but the first thing that came to mind.
You can use the TypeCode enumeration. Call the GetTypeCode method on classes that implement the IConvertible interface to obtain the type code for an instance of that class. IConvertible is implemented by Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String, so you can check for primitive types using this. More info on "Generic Type Checking".
Personally, I like method overloading:
public static class Extensions {
public static String Blank(this String me) {
return String.Empty;
}
public static T Blank<T>(this T me) {
var tot = typeof(T);
return tot.IsValueType
? default(T)
: (T)Activator.CreateInstance(tot)
;
}
}
class Program {
static void Main(string[] args) {
Object o = null;
String s = null;
int i = 6;
Console.WriteLine(o.Blank()); //"System.Object"
Console.WriteLine(s.Blank()); //""
Console.WriteLine(i.Blank()); //"0"
Console.ReadKey();
}
}
The discussion for String is not working here.
I had to have following code for generics to make it work -
private T createDefault()
{
{
if(typeof(T).IsValueType)
{
return default(T);
}
else if (typeof(T).Name == "String")
{
return (T)Convert.ChangeType(String.Empty,typeof(T));
}
else
{
return Activator.CreateInstance<T>();
}
}
}

Categories