How to parse a string into a nullable int - c#

I'm wanting to parse a string into a nullable int in C#. ie. I want to get back either the int value of the string or null if it can't be parsed.
I was kind of hoping that this would work
int? val = stringVal as int?;
But that won't work, so the way I'm doing it now is I've written this extension method
public static int? ParseNullableInt(this string value)
{
if (value == null || value.Trim() == string.Empty)
{
return null;
}
else
{
try
{
return int.Parse(value);
}
catch
{
return null;
}
}
}
Is there a better way of doing this?
EDIT: Thanks for the TryParse suggestions, I did know about that, but it worked out about the same. I'm more interested in knowing if there is a built-in framework method that will parse directly into a nullable int?

int.TryParse is probably a tad easier:
public static int? ToNullableInt(this string s)
{
int i;
if (int.TryParse(s, out i)) return i;
return null;
}
Edit #Glenn int.TryParse is "built into the framework". It and int.Parse are the way to parse strings to ints.

You can do this in one line, using the conditional operator and the fact that you can cast null to a nullable type (two lines, if you don't have a pre-existing int you can reuse for the output of TryParse):
Pre C#7:
int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? tempVal : (int?)null;
With C#7's updated syntax that allows you to declare an output variable in the method call, this gets even simpler.
int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;

[Updated to use modern C# as per #sblom's suggestion]
I had this problem and I ended up with this (after all, an if and 2 returns is soo long-winded!):
int? ToNullableInt (string val)
=> int.TryParse (val, out var i) ? (int?) i : null;
On a more serious note, try not to mix int, which is a C# keyword, with Int32, which is a .NET Framework BCL type - although it works, it just makes code look messy.

C# >= 7.1
var result = int.TryParse(foo, out var f) ? f : default;
See C# language versioning to ascertain what language version your project supports

Glenn Slaven: I'm more interested in knowing if
there is a built-in framework method
that will parse directly into a
nullable int?
There is this approach that will parse directly to a nullable int (and not just int) if the value is valid like null or empty string, but does throw an exception for invalid values so you will need to catch the exception and return the default value for those situations:
public static T Parse<T>(object value)
{
try { return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value.ToString()); }
catch { return default(T); }
}
This approach can still be used for non-nullable parses as well as nullable:
enum Fruit { Orange, Apple }
var res1 = Parse<Fruit>("Apple");
var res2 = Parse<Fruit?>("Banana");
var res3 = Parse<int?>("100") ?? 5; //use this for non-zero default
var res4 = Parse<Unit>("45%");
NB: There is an IsValid method on the converter you can use instead of capturing the exception (thrown exceptions does result in unnecessary overhead if expected). Unfortunately it only works since .NET 4 but there's still an issue where it doesn't check your locale when validating correct DateTime formats, see bug 93559.

Old topic, but how about:
public static int? ParseToNullableInt(this string value)
{
return String.IsNullOrEmpty(value) ? null : (int.Parse(value) as int?);
}
I like this better as the requriement where to parse null, the TryParse version would not throw an error on e.g. ToNullableInt32(XXX). That may introduce unwanted silent errors.

Try this:
public static int? ParseNullableInt(this string value)
{
int intValue;
if (int.TryParse(value, out intValue))
return intValue;
return null;
}

I feel my solution is a very clean and nice solution:
public static T? NullableParse<T>(string s) where T : struct
{
try
{
return (T)typeof(T).GetMethod("Parse", new[] {typeof(string)}).Invoke(null, new[] { s });
}
catch (Exception)
{
return null;
}
}
This is of course a generic solution which only require that the generics argument has a static method "Parse(string)". This works for numbers, boolean, DateTime, etc.

You can forget all other answers - there is a great generic solution:
http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/
This allows you to write very clean code like this:
string value = null;
int? x = value.ConvertOrDefault();
and also:
object obj = 1;
string value = null;
int x = 5;
if (value.TryConvert(out x))
Console.WriteLine("TryConvert example: " + x);
bool boolean = "false".ConvertOrDefault();
bool? nullableBoolean = "".ConvertOrDefault();
int integer = obj.ConvertOrDefault();
int negativeInteger = "-12123".ConvertOrDefault();
int? nullableInteger = value.ConvertOrDefault();
MyEnum enumValue = "SecondValue".ConvertOrDefault();
MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault();

I would suggest following extension methods for string parsing into int value with ability to define default value in case parsing is not possible:
public static int ParseInt(this string value, int defaultIntValue = 0)
{
return int.TryParse(value, out var parsedInt) ? parsedInt : defaultIntValue;
}
public static int? ParseNullableInt(this string value)
{
if (string.IsNullOrEmpty(value))
return null;
return value.ParseInt();
}

The following should work for any struct type. It is based off code by Matt Manela from MSDN forums. As Murph points out the exception handling could be expensive compared to using the Types dedicated TryParse method.
public static bool TryParseStruct<T>(this string value, out Nullable<T> result)
where T: struct
{
if (string.IsNullOrEmpty(value))
{
result = new Nullable<T>();
return true;
}
result = default(T);
try
{
IConvertible convertibleString = (IConvertible)value;
result = new Nullable<T>((T)convertibleString.ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture));
}
catch(InvalidCastException)
{
return false;
}
catch (FormatException)
{
return false;
}
return true;
}
These were the basic test cases I used.
string parseOne = "1";
int? resultOne;
bool successOne = parseOne.TryParseStruct<int>(out resultOne);
Assert.IsTrue(successOne);
Assert.AreEqual(1, resultOne);
string parseEmpty = string.Empty;
int? resultEmpty;
bool successEmpty = parseEmpty.TryParseStruct<int>(out resultEmpty);
Assert.IsTrue(successEmpty);
Assert.IsFalse(resultEmpty.HasValue);
string parseNull = null;
int? resultNull;
bool successNull = parseNull.TryParseStruct<int>(out resultNull);
Assert.IsTrue(successNull);
Assert.IsFalse(resultNull.HasValue);
string parseInvalid = "FooBar";
int? resultInvalid;
bool successInvalid = parseInvalid.TryParseStruct<int>(out resultInvalid);
Assert.IsFalse(successInvalid);

I'm more interested in knowing if there is a built-in framework method that will parse directly into a nullable int?
There isn't.

This solution is generic without reflection overhead.
public static Nullable<T> ParseNullable<T>(string s, Func<string, T> parser) where T : struct
{
if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(s.Trim())) return null;
else return parser(s);
}
static void Main(string[] args)
{
Nullable<int> i = ParseNullable("-1", int.Parse);
Nullable<float> dt = ParseNullable("3.14", float.Parse);
}

I felt I should share mine which is a bit more generic.
Usage:
var result = "123".ParseBy(int.Parse);
var result2 = "123".ParseBy<int>(int.TryParse);
Solution:
public static class NullableParse
{
public static Nullable<T> ParseBy<T>(this string input, Func<string, T> parser)
where T : struct
{
try
{
return parser(input);
}
catch (Exception exc)
{
return null;
}
}
public delegate bool TryParseDelegate<T>(string input, out T result);
public static Nullable<T> ParseBy<T>(this string input, TryParseDelegate<T> parser)
where T : struct
{
T t;
if (parser(input, out t)) return t;
return null;
}
}
First version is a slower since it requires a try-catch but it looks cleaner. If it won't be called many times with invalid strings, it is not that important.
If performance is an issue, please note that when using TryParse methods, you need to specify the type parameter of ParseBy as it can not be inferred by the compiler. I also had to define a delegate as out keyword can not be used within Func<>, but at least this time compiler does not require an explicit instance.
Finally, you can use it with other structs as well, i.e. decimal, DateTime, Guid, etc.

I found and adapted some code for a Generic NullableParser class. The full code is on my blog Nullable TryParse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace SomeNamespace
{
/// <summary>
/// A parser for nullable types. Will return null when parsing fails.
/// </summary>
/// <typeparam name="T"></typeparam>
///
public static class NullableParser<T> where T : struct
{
public delegate bool TryParseDelegate(string s, out T result);
/// <summary>
/// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method;
/// </summary>
/// <param name="text">Text to be parsed</param>
/// <param name="result">Value is true for parse succeeded</param>
/// <returns>bool</returns>
public static bool TryParse(string s, out Nullable<T> result)
{
bool success = false;
try
{
if (string.IsNullOrEmpty(s))
{
result = null;
success = true;
}
else
{
IConvertible convertableString = s as IConvertible;
if (convertableString != null)
{
result = new Nullable<T>((T)convertableString.ToType(typeof(T),
CultureInfo.CurrentCulture));
success = true;
}
else
{
success = false;
result = null;
}
}
}
catch
{
success = false;
result = null;
}
return success;
}
}
}

public static void Main(string[] args)
{
var myString = "abc";
int? myInt = ParseOnlyInt(myString);
// null
myString = "1234";
myInt = ParseOnlyInt(myString);
// 1234
}
private static int? ParseOnlyInt(string s)
{
return int.TryParse(s, out var i) ? i : (int?)null;
}

The cleaner way would be to write a separate function or extension method, but if you just want a one-liner:
string s;
int? i = s == null ? (int?)null : int.Parse(s);

You should never use an exception if you don't have to - the overhead is horrible.
The variations on TryParse solve the problem - if you want to get creative (to make your code look more elegant) you could probably do something with an extension method in 3.5 but the code would be more or less the same.

Using delegates, the following code is able to provide reusability if you find yourself needing the nullable parsing for more than one structure type. I've shown both the .Parse() and .TryParse() versions here.
This is an example usage:
NullableParser.TryParseInt(ViewState["Id"] as string);
And here is the code that gets you there...
public class NullableParser
{
public delegate T ParseDelegate<T>(string input) where T : struct;
public delegate bool TryParseDelegate<T>(string input, out T outtie) where T : struct;
private static T? Parse<T>(string input, ParseDelegate<T> DelegateTheParse) where T : struct
{
if (string.IsNullOrEmpty(input)) return null;
return DelegateTheParse(input);
}
private static T? TryParse<T>(string input, TryParseDelegate<T> DelegateTheTryParse) where T : struct
{
T x;
if (DelegateTheTryParse(input, out x)) return x;
return null;
}
public static int? ParseInt(string input)
{
return Parse<int>(input, new ParseDelegate<int>(int.Parse));
}
public static int? TryParseInt(string input)
{
return TryParse<int>(input, new TryParseDelegate<int>(int.TryParse));
}
public static bool? TryParseBool(string input)
{
return TryParse<bool>(input, new TryParseDelegate<bool>(bool.TryParse));
}
public static DateTime? TryParseDateTime(string input)
{
return TryParse<DateTime>(input, new TryParseDelegate<DateTime>(DateTime.TryParse));
}
}

I realise this is an old topic, but can't you simply:
(Nullable<int>)int.Parse(stringVal);
?

I've come up with this one, which has satisfied my requirements (I wanted my extension method to emulate as close as possible the return of the framework's TryParse, but without try{} catch{} blocks and without the compiler complaining about inferring a nullable type within the framework method)
private static bool TryParseNullableInt(this string s, out int? result)
{
int i;
result = int.TryParse(s, out i) ? (int?)i : null;
return result != null;
}

I suggest code bellow. You may work with exception, when convert error occured.
public static class Utils {
public static bool TryParse<Tin, Tout>(this Tin obj, Func<Tin, Tout> onConvert, Action<Tout> onFill, Action<Exception> onError) {
Tout value = default(Tout);
bool ret = true;
try {
value = onConvert(obj);
}
catch (Exception exc) {
onError(exc);
ret = false;
}
if (ret)
onFill(value);
return ret;
}
public static bool TryParse(this string str, Action<int?> onFill, Action<Exception> onError) {
return Utils.TryParse(str
, s => string.IsNullOrEmpty(s) ? null : (int?)int.Parse(s)
, onFill
, onError);
}
public static bool TryParse(this string str, Action<int> onFill, Action<Exception> onError) {
return Utils.TryParse(str
, s => int.Parse(s)
, onFill
, onError);
}
}
Use this extension method in code (fill int? Age property of a person class):
string ageStr = AgeTextBox.Text;
Utils.TryParse(ageStr, i => person.Age = i, exc => { MessageBox.Show(exc.Message); });
OR
AgeTextBox.Text.TryParse(i => person.Age = i, exc => { MessageBox.Show(exc.Message); });

Related

c# generic method take function as param

I'm trying to understand a way to pass in two or more extension methods to a another method as parameters and return the value back. I have extension methods for each datatype to return a value or default value and a value or a null value and also a value or throw an error. The code has scenarios that would require each of these, but it also has scenarios combining the results from each of these in a ternary test, examples below.
public static int IntOrError(this object val, string fieldName)
{
int test;
if (string.IsNullOrEmpty(val.ToString()))
{
throw new Exception("I threw it");
}
else if (int.TryParse(val.ToString(), out test) == false)
{
throw new Exception("Bad Int Value");
}
else
{
return test;
}
}
public static int IntOrDefault(this object val)
{
int test;
if (int.TryParse(val.ToString(), out test))
{
return test;
}
else
{
return -1;
}
}
public static int? IntOrNull(this object val)
{
int test;
if (int.TryParse(val.ToString(), out test))
{
return test;
}
else
{
return -1;
}
}
I've been trying to make a reusable method that could process taking in in this example IntOrNull, IntOrDefault and IntOrError and pass back the int or throw an error. So far I've only been able to get this to work. I'm trying to avoid creating this method for every datatype also.
public static int IntDefaultValidated(this object val, string fieldName)
{
return val.IntOrNUll() != null
? val.IntOrDefaultError(fieldName)
: val.IntOrDefault();
}
I am trying to get a generic method or a functional style of method that will take in the extension methods as params and return back the value.
I'm hoping to avoid reflection if possible.
//just a psuedo example
var intVal = "";
var valRet = DefaultValidated(intVal.IntOrNull(), intVal.IntOrdefault(), intVal.IntOrDefaultError("intVal"));
//or maybe like this, or some combination of extension, generic, functional
var valRet = intVal.DefaultOrValidated(IntOrNull(intVal), IntOrDefault(intVal), IntOrDefaultError(intVal, "intVal"));
Your logic of IntOrDefault, IntOrNull and IntDefaultValidated does not really make sense, so I think it's just an usage example.
Beside this - my advice is to implement your functions as generic extensions.
public static class MyExtensions
{
public static T ValueOrError<T>(this object val)
{
try
{
// http://stackoverflow.com/a/8633/2534462
return (T)Convert.ChangeType(val, typeof(T));
} catch
{
throw new Exception("Throw your own exception if you really want to");
}
}
public static T ValueOrDefault<T>(this object val, T defaultValue)
{
try
{
return val.ValueOrError<T>();
}
catch
{
return defaultValue; // usally use: return default(T);
}
}
public static T ValueOrNull<T>(this object val)
{
try
{
return val.ValueOrError<T>();
}
catch
{
// check for nullable type
//https://msdn.microsoft.com/de-de/library/ms366789.aspx
var type = typeof(T);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return default(T); // null on nullable types
} else {
throw new Exception("Callable only on Nullable types");
// my return another default value ??? .. -1 ???
}
}
}
public static T ValueDefaultValidated<T>(this object val, T defaultValue)
{
return val.ValueOrNull<T>() != null
? val.ValueOrError<T>()
: val.ValueOrDefault<T>(defaultValue);
}
}
Usage
string aNumber = "10";
var intNumber = aNumber.ValueDefaultValidated(-1); // int
var decNumber = aNumber.ValueDefaultValidated(-1m); // decimal
string naNumber = "whatever";
var defaultInt = naNumber.ValueOrDefault(-1); // int
var defaultDecimal = naNumber.ValueDefaultValidated<decimal?>(-1m);
// ValueOrNull ist undefined on Non-Nullable-Type.
var undefined = naNumber.ValueDefaultValidated<decimal>(-1m);
Something like this?
public static T Convert<T>(this object input)
{
if (typeof (T) == input.GetType())
return (T) input;
var stringValue = input.ToString();
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter.CanConvertFrom(typeof(string)))
{
return (T)converter.ConvertFrom(stringValue);
}
return default(T);
}
This test passes. May be this is not exactly what you need but still.
[Fact]
public void TestMethod1()
{
object testInt = 1;
object testString = "123";
double testDouble = 1.0;
string testWrong = "abc";
int resultInt = testInt.Convert<int>();
string resultString = testString.Convert<string>();
int resultIntString = testString.Convert<int>();
int dbl2int = testDouble.Convert<int>();
Assert.Throws<Exception>(() => testWrong.Convert<int>());
Assert.Equal(1, resultInt);
Assert.Equal("123", resultString);
Assert.Equal(123, resultIntString);
Assert.Equal(1, dbl2int);
}

How do I read a string with LINQ to XML and set an enum value? [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);
}

how to create a custom cast explicit in c #?

Have this code:
string abc = "123456";
To convert to int should I use convert:
int abcInt = Convert.ToInt32(abc);
The problem is that if not a number I have an exception see returning zero so my final code will look like:
try{ int abcInt = Convert.ToInt32(abc); }catch(Exception e){ int abcInt = 0; }
So you see that I decided to create a book that made ​​me an object returning zero numeric without exception if it failed, so could keep most flexible programming without much junk code:
int abcInt = Libs.str.safeInt(abc);
The code is:
public int safeInt(object ob)
{
if ((ob == null) || (String.IsNullOrEmpty(ob.ToString())))
return 0;
try
{
return Convert.ToInt32(
System.Text.RegularExpressions.Regex.Replace(ob.ToString(), #"#[^Ee0-9\.\,]+#i", "").
ToString(CultureInfo.InvariantCulture.NumberFormat)
);
}
catch (FormatException e)
{
return 0;
}
}
But I want to go one step further and do something like this:
int abcInt = (safeInt)abc;
how to do?
Can not convert type 'string' to 'Libs.safeInt.safeInt'
You should just use Int32.TryParse:
int abcInt;
if(!Int32.TryParse(abc, out abcInt)) {
abcInt = 0;
}
// abcInt has been parsed to an int, or defaulted to zero
Note that this can be shortened to
int abcInt;
Int32.TryParse(abc, out abcInt);
if all that you want is the default value to be zero because:
When this method returns, contains the 32-bit signed integer value equivalent to the number contained in s, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null, is not of the correct format, or represents a number less than MinValue or greater than MaxValue. This parameter is passed uninitialized.
I actually recommend against writing it this way because now you can't distinguish between abc = "0" and abc = "garbage"; both with exhibit exactly the same behavior with the above two lines of code. With the initial version above (i.e., the if, you can distinguish the two cases if you need to; silently ignoring errors is generally a bad idea).
That said, if you absolutely are dying to know how to implement an explicit cast operator, you proceed like this:
class SafeInt32 {
private readonly int value;
public int Value { get { return this.value; } }
private readonly string source;
public string Source { get { return this.source; } }
private readonly bool successful;
public bool Successful { get { return this.successful; } }
public SafeInt32(string source) {
this.source = source;
this.successful = Int32.TryParse(source, out this.value);
}
public static explicit operator SafeInt32(string source) {
return new SafeInt32(source);
}
public static implicit operator int(SafeInt32 safeInt32) {
return safeInt32.Value;
}
}
Usage:
int abcInt = (SafeInt32)"123456";
Note that we had to define an explicit cast operator to cast a string to a SafeInt32, and an implicit cast operator to cast a SafeInt32 to an int to achieve your desired syntax. The latter is necessary so that the compiler can silently convert the result of (SafeInt32)"123456" to an int.
Again, I recommend against this; use Int32.TryParse.
You can leverage implicit and explicit operators to do what you want, yes. You can also use int.TryParse to avoid using exceptions for control flow.
public struct SafeInt
{
public int Value { get; private set; }
public static implicit operator int(SafeInt safeInt)
{
return safeInt.Value;
}
public static explicit operator SafeInt(string obj)
{
return new SafeInt() { Value = SafeParse(obj) };
}
public static int SafeParse(object value)
{
int output;
int.TryParse((value ?? "0").ToString(), out output);
return output;
}
}
I mean, you should use int.TryParse, but if you're dead-set on the cast syntax:
public class SafeInt
{
private int _value;
private SafeInt() {}
public static explicit operator SafeInt(string str)
{
int x;
int.TryParse(str, out x);
SafeInt si = new SafeInt();
si._value = x;
return si;
}
public static implicit operator int(SafeInt x)
{
return x._value;
}
public override string ToString()
{
return _value.ToString();
}
}
You can then use it like this:
int x = (SafeInt)"234234";
First, let me just go on record saying that you may not want to do this.
Silently ignoring problems like this can cause other types of problems, such as a customer asking "Why is this total over here always wrong?".
Having said that, let's see how you can do what you want before I give you a better option:
void Main()
{
int a = (SafeInt)"123";
a.Dump();
int b = (SafeInt)"xyz";
b.Dump();
}
public struct SafeInt
{
private readonly int _Value;
public SafeInt(int value)
{
_Value = value;
}
public SafeInt(int? value)
{
_Value = value ?? 0;
}
public int Value
{
get
{
return _Value;
}
}
public static implicit operator int(SafeInt s)
{
return s.Value;
}
public static implicit operator SafeInt(string s)
{
try
{
return new SafeInt(Convert.ToInt32(s));
}
catch (FormatException)
{
return new SafeInt();
}
}
}
This will print out:
123
0
Now, my advice is to stay away from this. Instead, use this:
void Main()
{
TryParse("123").Dump();
TryParse("xyz").Dump();
}
public static int TryParse(string s, int errorValue = 0)
{
int result;
if (int.TryParse(s, out result))
return result;
return errorValue;
}
Note that if you always want 0 as the value to return upon an error, there's even a much simpler way built into the system, this:
int value;
int.TryParse("123", out value);
Here we disregard the Boolean result from TryParse, because if TryParse fails, it'll set the parameter to 0.
I'd recommend that you do not do this. I find explicit and implicit conversions to be hard to discover, read, and use, compared to simpler static methods and/or constructors. Also, are you aware of the int.TryParse method? That might be a better solution for you:
public static int SafeInt(object value)
{
int i;
int.TryParse(value.ToString(), out i);
return i;
}
Or, more directly to answer your question, you can use explicit and implicit conversions on a SafeInt class to do this:
public class SafeInt
{
public int Value { get; set; }
public static implicit operator int(SafeInt si)
{
return si.Value;
}
public static explicit operator SafeInt(String str)
{
return new SafeInt { Value = Libs.str.safeInt(str) };
}
}
Use like:
int i = (SafeInt)"123";

How to ask if a string variable can be parsed to an int variable?

What can I use that will return a boolean variable that will state if I can parse a string safely or not?
1847 will return true
18o2 will return false
And please, nothing too complicated...
You can use int.TryParse
int result = 0;
bool success = int.TryParse("123", out result);
Here success will have true if parsed successfully and false other wise and result will have parse int value.
Use int.TryParse:
int i;
bool canBeParsed = int.TryParse("1847", out i);
if(canBeParsed)
{
Console.Write("Number is: " + i);
}
var str = "18o2"
int num = 0;
bool canBeParsed = Int32.TryParse(str, out num);
You should take a look on the TryParse method
I have been using these extension methods for years. Maybe a bit more "complicated" in the beginning but their use is very simple. You can extend most of the simple values types including Int16, Int64, Boolean, DateTime, etc. using a similar pattern.
using System;
namespace MyLibrary
{
public static class StringExtensions
{
public static Int32? AsInt32(this string s)
{
Int32 result;
return Int32.TryParse(s, out result) ? result : (Int32?)null;
}
public static bool IsInt32(this string s)
{
return s.AsInt32().HasValue;
}
public static Int32 ToInt32(this string s)
{
return Int32.Parse(s);
}
}
}
To use these, just include MyLibrary in the list of namespaces with a using declaration.
"1847".IsInt32(); // true
"18o2".IsInt32(); // false
var a = "1847".AsInt32();
a.HasValue; //true
var b = "18o2".AsInt32();
b.HasValue; // false;
"18o2".ToInt32(); // with throw an exception since it can't be parsed.

int.TryParse syntatic sugar

int.TryPrase is great and all, but there is only one problem...it takes at least two lines of code to use:
int intValue;
string stringValue = "123";
int.TryParse(stringValue, out intValue);
....
Of course I can do something like:
string stringValue = "123";
int intValue = Convert.ToInt32(string.IsNullOrWhiteSpace(stringValue) ? 0 : stringValue);
on just one line of code.
How can I perform some magic to get int.TryParse to use a one liner, or is there yet a third alternative out there?
Thanks!
Bezden answered the question best, but in reality I plan on using Reddogs solution.
int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0;
Maybe use an extension method:
public static class StringExtensions
{
public static int TryParse(this string input, int valueIfNotConverted)
{
int value;
if (Int32.TryParse(input, out value))
{
return value;
}
return valueIfNotConverted;
}
}
And usage:
string x = "1234";
int value = x.TryParse(0);
Edit: And of course you can add the obvious overload that already sets the default value to zero if that is your wish.
This answer is only for those who use at least C# 7.
You can now declare the out parameter inline.
int.TryParse("123", out var result);
Exemplary usage:
if (int.TryParse("123", out var result)) {
//do something with the successfully parsed integer
Console.WriteLine(result);
} else {
Console.WriteLine("That wasn't an integer!");
}
MSDN: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#out-variables
I would create an extension method out of this.
public static int? AsInt32(this string s)
{
int value;
if (int.TryParse(s, out value))
return value;
return null;
}
I don't think there is anything really beautiful, but if you like this you get it down to one row:
string stringValue = "123"
int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0;
Check out the StringExtensions class. It contains an AsInt(String,Int32) extension method that will attempt to convert a string and if unsuccessful populate it with the supplied Int32 value as default.
Example:
var intValue = "123".AsInt(-1);
int val2 = "asd".AsInt(-1);
//Output : -1
int val3 = "123".AsInt(-1);
//Output : 123
You need to have System.Web.WebPages namespace.
One last addition to this NINE year-old question :). Bool parsing is a little different because if parsing fails, you don't want to return a default value, you want to return a NULL. This line does this (as of C# 7, I think):
return bool.TryParse(value, out bool result) ? (bool?)result : null;
That cast of the result is necessary, otherwise it cannot reconcile the differing types of the two return values.
In C# 7.0+ you can use inline variable declaration.
If parse successes - intValue = its parsed value.
If parse fails - intValue = 0.
Code:
int.TryParse(stringValue, out int intValue);
Drawback:
You cannot differentiate between a 0 value and a non parsed value.
You do not WANT to make int.TryParse() one line. Why? Because you can't make an assignment to intValue if the input string isn't a valid integer. The whole point of TryParse() is to allow you to test for good input and degrade gracefully, rather than having to catch an exception.
Int.TryParse() is already a shortcut so you don't have to test for a valid int and do the assignment in two steps... that's as far as you want to take it.
Because it essentially returns two values (success and the value), we really do need the two lines.
You could try a wrapper class, ie:
void Main()
{
var result = simpleIntParser.TryParse("1");
if(result)
{
Console.WriteLine((int)result);
} else {
Console.WriteLine("Failed");
}
result = simpleIntParser.TryParse("a");
if(result)
{
Console.WriteLine((int)result);
} else {
Console.WriteLine("Failed");
}
}
public class simpleIntParser
{
public bool result {get; private set;}
public int value {get; private set;}
private simpleIntParser(bool result, int value)
{
this.result = result;
this.value = value;
}
public static simpleIntParser TryParse(String strValue)
{
int value;
var result = int.TryParse(strValue, out value);
return new simpleIntParser(result, value);
}
public static implicit operator int(simpleIntParser m)
{
return m.value;
}
public static implicit operator bool(simpleIntParser m)
{
return m.result;
}
}
It requires casting if the type is ambiguous (i.e. for Console.WriteLine()), but if you pass it as an integer parameter for example, no casting is required
This technically isn't the most efficient as it parses the string twice, but it does get it into one line.
Result as Nullable<int>:
int? ToInt(string value) => int.TryParse(value, out _) ? int.Parse(value) : (int?)null;

Categories

Resources