c# generic method take function as param - c#

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);
}

Related

How can I convert an object to a nullable generic in C#?

I have a class which contains answers for questions
The answers are stored in a string
I have created a method like so:
public void set_answer(object obj){
.....
}
which will take as an arguement a variable, and according to the question type will change it into a string representation, so for example if the answer is a string it will keep it as it is, if it is a DateTime it will change it to a yyyy-MM-dd format plus about 8 other transformations
I wish to create the opposite method, which will return the answer in the original type
I have the following code:
public T? get_answer<T>() {
//this means that the answer has not been set yet
if (string.IsNullOrWhiteSpace(_answer)) return null;
object reply = null;
switch (_answer_type) {
...do stuff here to transform the string to the correct type, which will match T
}
<here is the problem>
}
At the end of this code, the reply variable will contain either null or a variable of type T
how can I return that value?
in my code I will be using it like this :
DateTime? date = question.get_answer<DateTime>();
which should return null if no answer has been set yet or the request was for an incorrect type (i.e. asked for a datetime answer on a Tupple question)
Thanks in advance for any help you can provide
If you have a MyMethod<T> and for the most part it consists of code like if (T is Type1) {...} else if (T is Type2) {...} else if [etc], then very often you shouldn't be using a generic method in the first place.
In such a case I would recommend to use this:
public class MyClass
{
public string _answer;
public DateTime? GetDate()
{
DateTime result;
if (DateTime.TryParse(_answer, out result)) return result;
return null;
}
public int? GetInt()
{
int result;
if (int.TryParse(_answer, out result)) return result;
return null;
}
// etc
}
and to test it:
public void TestIt()
{
var x = new MyClass { _answer = "gaga" };
var d = x.GetDate();
var i = x.GetInt();
// etc
}
Or if you must use a single obj...
public void TestIt()
{
var x = new MyClass { _answer = "gaga" };
object obj = x.GetDate();
if (obj == null) obj = x.GetInt();
// etc
}
Or in one statement:
public void TestIt()
{
var x = new MyClass { _answer = "gaga" };
var obj = (object) x.GetDate() ?? x.GetInt() /* ?? [etc] */ ;
}

How to convert optional pointer argument from C++ code to C#

I have function in c++ something like this:
// C++
bool Foo(int* retVal = NULL)
{
// ...
if (retVal != NULL)
*retVal = 5;
// ...
return true;
}
And I can use functions in two ways:
int ret;
Foo(&ret);
Foo();
When I write code in C# I used ref keyword:
// C#
bool Foo(ref int retVal = null)
{
// ...
if (retVal != null)
{
retVal = 5;
}
// ...
return true;
}
but compiler said:
A ref or out parameter cannot have a default value.
How can I solve this problem?
The simplest way would be to just write an overload:
bool Foo()
{
int notUsed;
return Foo(ref notUsed);
}
bool Foo(ref int retVal)
{
// ...
retVal = 5;
// ...
return true;
}
If you actually need to know whether the ref value is needed, well, you can still use pointers, but you'll need an unsafe context:
unsafe bool Foo()
{
return Foo(null);
}
unsafe bool Foo(ref int retVal)
{
return Foo(&retVal);
}
private unsafe bool Foo(int* retVal)
{
// ...
if (retVal != null)
{
*retVal = 5;
}
// ...
return true;
}
Or, without unsafe as suggested in the comments, as pointers in C# may be considered as heavy artillery:
bool Foo()
{
var notNeeded = 0;
return Foo(ref notNeeded, false);
}
bool Foo(ref int retVal)
{
return Foo(ref retVal, true);
}
private bool Foo(ref int retVal, bool retValNeeded)
{
// ...
if (retValNeeded)
{
retVal = 5;
}
// ...
return true;
}
The ref of C# is more similar to the & (reference) of C++ than to the * of C and C++ (pointer). As C++ references, they must reference something.
Now, you could:
public class OptionalRef<T>
{
public T Value { get; set; }
public static implicit operator OptionalRef<T>(T value)
{
return new OptionalRef<T> { Value = value };
}
public static implicit operator T(OptionalRef<T> optional)
{
return optional.Value;
}
public override string ToString()
{
return Value != null ? Value.ToString() : null;
}
}
then
static bool Foo(OptionalRef<int> retVal = null)
{
// ...
if (retVal != null)
{
retVal.Value = 5;
}
// ...
return true;
}
and you use it like:
Foo(); // null passed
Foo(null); // same
Foo(5); // not interested if the value is changed
// Full use
OptionalRef<int> val = 5;
Foo(val);
int ret = val;
note that I'm not fully endorsing the semantics I wrote
It is more a case of you asked for something, I gave you something, no questions asked
I'd go about this one of two ways. If you REALLY want to have a reference to your object you can wrap that in a class. Those are always passed by reference so you'll get your modification the way you want and you can instantiate it to null.
Here is an example.
public class HolderObject
{
public string myStr {get; set;}
}
public class Program
{
public static void Main()
{
var xyz = new HolderObject() {
myStr = "1234"
};
Console.WriteLine(xyz.myStr);
FixString(xyz);
Console.WriteLine(xyz.myStr);
FixString();
Console.WriteLine(xyz.myStr);
}
private static bool FixString(HolderObject input = null)
{
if (input != null)
input.myStr = "test";
return true;
}
}
prints
1234
test
Another solution is to overload your function.
bool Foo()
{
// ...
return true;
}
bool Foo(ref int retVal = null)
{
// ...
if (retVal != null)
{
retVal = 5;
}
return Foo();
}
I REALLY don't like this. I'm actually in the middle of working on code in C# that has been pulled directly from C++. Functions that are nested 6 or 7 layers deep modifying an object that was passed by reference. That is hard to read and if you look at the code analysis warnings, it will suggest you don't use ref values.
If you can I'd move away from passing by ref as much as possible and return the value back that has been modified. Or pass an object back that contains both your bool and your new value.

How can I make a field in a class be set to false if the value being set is a null?

I have the following:
var result2 = result1
.Select((t, index) => new {
Answer = t.Answer,
Answers = JSON.FromJSONString<Answer2>(t.AnswerJSON)
});
return Ok(result2);
public class Answer2 {
public bool? Correct; // Maybe this should be a property
public bool Response; // Maybe this should be a property
}
And my String > object function:
public static T FromJSONString<T>(this string obj) where T : class
{
if (obj == null)
{
return null;
}
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(obj)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
T ret = (T)ser.ReadObject(stream);
return ret;
}
}
Is there a way with this that I could make the Response field be false if a null is present for Response in the JSON string or if there is no value for Response in the JSON string?
Note: I had a suggestion about using a property and I think that would work but I am not sure how to do it in practice.
You should use a property for this matter:
public class Answer2 {
private bool correct; // This field has no need to be nullable
public bool? Correct
{
get { return correct; }
set { correct = value.GetValueOrDefault(); }
}
}
Following the Q and A section, you should be able to do it on a property like this:
private bool? whatever;
public bool? Whatever
{
get { return whatever; }
set
{
if (value == null)
whatever = false;
else
whatever = value;
}
}
This way you can pass a null value to the property, but it can only have a bool (true/false) value in it.

Manually infering variable types from a list of examples in string format

I have a List<string> of sample data points that I have read from the file. I am looking for a way to infer the most appropriate type for the examples that are in the list. For example imagine the list is initialized like the following:
var samples = new List<string>()
{
"1",
"2",
"2.01"
};
I am looking for a method that accepts this list and returns System.double. I am wondering if there is any internal C# method that I can use. my data can be either int, double or a string so I can always try to cast them into int and if it fails cast it into double and if that fails for all element return System.string. Is there any easier way of doing it?
Methods are supposed to have a single return type, there are ways around this but it would be better to return a string and just have wherever you're calling from handle the string how you want for example.
String s=method(samples);
int i;
try
{
i=s.ToDecimal();
}
catch (FormatException e)
{
Console.WriteLine("Input string is not a sequence of digits.");
}
catch (OverflowException e)
{
Console.WriteLine("The number cannot fit in an Int32.");
}
As far as I know there's nothing built-in, but you could write your own:
public delegate bool TryParseDelegate<T>(string str, out T value);
public static Tuple<Func<string, bool>, Type> ParsesAs<T>(TryParseDelegate<T> d)
{
Func<string, bool> f = s =>
{
T val;
return d(s, out val);
};
return Tuple.Create(f, typeof(T));
}
public static Type FindBestType(List<string> input)
{
var parsers = new List<Tuple<Func<string, bool>, Type>>
{
ParsesAs<int>(int.TryParse),
ParsesAs<double>(double.TryParse)
};
int i = 0;
foreach (string str in input)
{
while (i < parsers.Count && !parsers[i].Item1(str))
{
i++;
}
if (i == parsers.Count) break;
}
return i == parsers.Count ? typeof(string) : parsers[i].Item2;
}
Assuming it's only int/double/string you can do something like this. It's not optimized by any means. Just something straightforward that may get you on the right track.
public static Type InferType(List<string> samples)
{
Type stringType= typeof(string);
Type intType = typeof(int);
Type doubleType = typeof(double);
List<Type> types = new List<Type>();
for (int i = 0; i < samples.Count; i++)
{
int intRepresentation;
double doubleRepresentation;
if (int.TryParse(samples[i], out intRepresentation))
{
types.Add(intType);
}
else if (double.TryParse(samples[i], out doubleRepresentation))
{
types.Add(doubleType);
}
else
{
types.Add(stringType);
break;
}
}
return types.Any(e => e == stringType) ? stringType :
types.Any(e => e == doubleType) ? doubleType :
intType;
}

How to parse a string into a nullable int

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); });

Categories

Resources