how to parse or convert - c#

Is there easyer way to parse in c# then this:
float temp;
if (float.TryParse(quantity.ToString(), out temp))
{
noteProduct.Quantity = temp;
}
Thanks

You can of course use float.Parse("string") - but it will throw exception if it can't parse it.
For me this is good and safe way of parsing.

TryParse is the best way, if you want to avoid possible exceptions.
If you are certain that quantity will always be a valid float you can simply use Parse:
noteProduct.Quantity = float.Parse(quantity.ToString());
However, this will throw an exception if quantity.ToString() is not a valid float.

As others have said, yes there are easier ways, but that doesn't mean you should necessarily use them. Easier does not always mean better. In this example I'd actually recommend you make your parsing more complicated - by making it culture sensetive..
float temp;
if (Single.TryParse(quantity.ToString(), NumberStyles.Float, CultureInfo.CurentCulture, out temp)
{
noteProduct.Quantity = temp;
}

This is how I solved it. This is more easier to use instead of declaring temp variables and make if statements.
public class Parsers
{
private Parsers() { }
public static void SetLong(ref long item, object value)
{
long temp;
if (value != null && long.TryParse(value.ToString(), out temp)) { item = temp; }
}
public static void SetDateTime(ref DateTime item, object value)
{
DateTime temp;
if (value != null && DateTime.TryParse(value.ToString(), out temp)) { item = temp; }
}
public static void SetInt(ref int item, object value)
{
int temp;
if (value != null && int.TryParse(value.ToString(), out temp)) { item = temp; }
}
public static void SetString(ref string item, object value)
{
if (value != null) { item = value.ToString(); }
}
}

Related

C# - Converting object to int without casting

I have a method that returns a type of object based on the given column (a database class). However, when I assign the object the compiler throws an error saying it cannot implicitly convert type of object to int. How can I convert it without casting?
It looks better as:
this.Id = datum["Id"];
But now I have to include a cast, which makes the code a bit less clean and harder to code:
this.Id = (int)datum["Id"];
Here's my code:
public object this[string name]
{
get
{
object result;
if (this.Dictionary.ContainsKey(name))
{
if (this.Dictionary[name] is DBNull)
{
result = null;
}
else if (this.Dictionary[name] is byte && Meta.IsBool(this.Table, name))
{
result = (byte)this.Dictionary[name] > 0;
}
else
{
result = this.Dictionary[name];
}
}
else
{
result = default(object);
}
return result;
}
set
{
if (value is DateTime)
{
if (Meta.IsDate(this.Table, name))
{
value = ((DateTime)value).ToString("yyyy-MM-dd");
}
else if (Meta.IsDateTime(this.Table, name))
{
value = ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
}
}
if (this.Dictionary.ContainsKey(name))
{
this.Dictionary[name] = value;
}
else
{
this.Dictionary.Add(name, value);
}
}
}
You could change your indexer signature to:
public dynamic this[string name]
That would then make the conversion dynamic at execution time.
Personally, I prefer the cast approach though. It makes it clear that this is something that can fail - that you're telling the compiler that you have information which isn't available to it.
As an aside, your code can be written rather more simply, taking advantage of Dictionary<,>.TryGetValue and the behaviour of the dictionary indexer for setting:
public object this[string name]
{
get
{
object result;
if (Dictionary.TryGetValue(name, out result))
{
if (result is DBNull)
{
result = null;
}
else if (result is byte && Meta.IsBool(this.Table, name))
{
result = (byte) result > 0;
}
}
return result;
}
set
{
// TODO: Byte/bool conversions?
if (value is DateTime)
{
// Note use of invariant culture here. You almost certainly
// want this, given the format you're using. Preferably,
// avoid the string conversions entirely, but...
DateTime dateTime = (DateTime) value;
if (Meta.IsDate(this.Table, name))
{
value = dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
else if (Meta.IsDateTime(this.Table, name))
{
value = dateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
}
}
Dictionary[name] = value;
}
}
Use class Convert:
Convert.ToInt32(datum["Id"]);
If you didn't need to state in your code that you are casting from object to int, then the programming language would not be helping you avoid mistakes.
C# does have a feature where you can switch off static type checking for specific variables: make your indexer return dynamic:
public dynamic this[string name]
Then you'll be able to say:
int n = datum["Id"];
But the downside is that you won't find out if this is correct until runtime.
You can do an extension method.
Create a class like this.
public static class ExtensionMethods
{
public static int AsInt(this object obj)
{
return (int)obj; // add additional code checks here
}
}
Then in your actual code all you have to do is call the extension method like this.
this.Id = datum["Id"].AsInt();
I know this may look the same as the cast but it happens underneath the method call AsInt and your code is cleaner and easier to read since AsInt is fluent and definitive.

Is there a try Convert.ToInt32... avoiding exceptions

I'd like to know if there is a "safe" way to convert an object to an int, avoiding exceptions.
I'm looking for something like public static bool TryToInt32(object value, out int result);
I know I could make something like this:
public static bool TryToInt32(object value, out int result)
{
try
{
result = Convert.ToInt32(value);
return true;
}
catch
{
result = 0;
return false;
}
}
But I'd rather avoid exceptions, because they are slowing down the process.
I think this is more elegant, but it's still "cheap":
public static bool TryToInt32(object value, out int result)
{
if (value == null)
{
result = 0;
return false;
}
return int.TryParse(value.ToString(), out result);
}
Does anyone have better ideas?
UPDATE:
This sounds a little like splitting hairs, but converting an object to string forces the implementer to create a clear ToString() function. For example:
public class Percentage
{
public int Value { get; set; }
public override string ToString()
{
return string.Format("{0}%", Value);
}
}
Percentage p = new Percentage();
p.Value = 50;
int v;
if (int.TryParse(p.ToString(), out v))
{
}
This goes wrong, I can do two things here, or implement the IConvertable like this:
public static bool ToInt32(object value, out int result)
{
if (value == null)
{
result = 0;
return false;
}
if (value is IConvertible)
{
result = ((IConvertible)value).ToInt32(Thread.CurrentThread.CurrentCulture);
return true;
}
return int.TryParse(value.ToString(), out result);
}
But the ToInt32 method of the IConvertible cannot be canceled. So if it's not possible to convert the value, an exception cannot be avoided.
Or two: Is there a way to check if the object contains a implicit operator?
This is very poor:
if (value.GetType().GetMethods().FirstOrDefault(method => method.Name == "op_Implicit" && method.ReturnType == typeof(int)) != null)
{
result = (int)value;
return true;
}
int variable = 0;
int.TryParse(stringValue, out variable);
If it can't be parsed, the variable will be 0. See http://msdn.microsoft.com/en-us/library/f02979c7.aspx
Spurring from the comments. The response is no. You can't do what Convert.ToInt32(object) does without having throwed exceptions. You can do something similar (and you already did it). The only thing I would optimize is the case of value already an int.
if (value is int)
return (int)value;
You can't do as Convert.ToInt32(object) because Convert.ToInt32(object) doesn't simply test if value is short, int, long, ushort, ... and then cast them. It checks if the value is IConvertible. If yes it uses the IConvertible.ToInt32. Sadly the interface IConvertible is quite poor: it doesn't have non-throwing methods (IConvertible.Try*)
While stupid (but perhaps not too much), someone could make for example a UnixDateTime struct: (UnixTime is the number of seconds from midnight 1970-01-01), where the IConvertible.ToInt32 returns this number of seconds, while the ToString() returns a formatted date. All the int.TryParse(value.ToString(), out parsed) would choke, while the Convert.ToInt32 would work flawlessly.
This version using a type converter would only convert to string as a last resort but also not throw an exception:
public static bool TryToInt32(object value, out int result)
{
if (value == null)
{
result = 0;
return false;
}
var typeConverter = System.ComponentModel.TypeDescriptor.GetConverter(value);
if (typeConverter != null && typeConverter.CanConvertTo(typeof(int)))
{
var convertTo = typeConverter.ConvertTo(value, typeof(int));
if (convertTo != null)
{
result = (int)convertTo;
return true;
}
}
return int.TryParse(value.ToString(), out result);
}
No need to re-invent the wheel here. use int.TryParse to achieve your goal. It returns a bool to show that value is parsed or not. and if parsed the result is saved in the output variable.
int result;
object a = 5;
if(int.TryParse(a.ToString(),out result))
{
Console.WriteLine("value is parsed"); //will print 5
}   
object b = a5;
if(int.TryParse(b.ToString(),out result))
{
   Console.WriteLine("value is parsed");  
}
else
{
Console.WriteLine("input is not a valid integer");  //will print this
}
Return a nullable int. that way you know whether you parsed 0.
int? value = int.TryParse(stringValue, out int outValue)
? outValue
: default(int?);
I would use a mixture of what you are already doing;
Check if the object is null - return false and the value 0;
Attempt to convert directly - if successful, return true and the converted value
Attempt to parse value.ToString() - if successfull, return true and the parsed value
Any other case - Return false and the value 0, as object is not convertible/parsible
The resulting code:
public static bool TryToInt32(object value, out int result)
{
result = 0;
if (value == null)
{
return false;
}
//Try to convert directly
try
{
result = Convert.ToInt32(value);
return true;
}
catch
{
//Could not convert, moving on
}
//Try to parse string-representation
if (Int32.TryParse(value.ToString(), out result))
{
return true;
}
//If parsing also failed, object cannot be converted or paresed
return false;
}
I wrote this mess, looking at it makes me sad.
using System;
using System.Globalization;
internal static class ObjectExt
{
internal static bool TryConvertToDouble(object value, out double result)
{
if (value == null || value is bool)
{
result = 0;
return false;
}
if (value is double)
{
result = (double)value;
return true;
}
var text = value as string;
if (text != null)
{
return double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
}
var convertible = value as IConvertible;
if (convertible == null)
{
result = 0;
return false;
}
try
{
result = convertible.ToDouble(CultureInfo.InvariantCulture);
return true;
}
catch (Exception)
{
result = 0;
return false;
}
}
}
Edit
Notice now I answered for double when the question was int, keeping it any way. Maybe useful for someone.
This is how I like to do it:
object v = someValue;
if (int.TryParse($"{v}", out var extractedValue))
{
// do something with extractedValue
}

String to numeric conversion in c#

I am trying to write a function to convert the contents of a string "12345" to an int.
If the string is blank i would like to return null (uninitialized), not the value 0.
Problem is, functions do not return un-initialized values.
My code will not compile as Retval can return an uninitialized value......
My attempt so far:
public int ConvertStringToNumber(String TheString)
{
// Uninitialized
int Retval;
if (TheString.Length > 0)
{
// We have a valid string
if (Int32.TryParse(TheString, out Retval))
{
// We have a valid Number
}
}
// Return the number or null
return Retval;
}
Can you use Nullable int ? it will allow set as nullable . See here : http://www.codeproject.com/Articles/11854/C-2-0-Nullable-Types
You can use a nullable int (more info here).
Nullable types can represent all the values of an underlying type, and
an additional null value.
public int? ConvertStringToNumber(String TheString)
{
int retval;
bool isInt = Int32.TryParse(TheString, out retval);
return isInt ? retval : null;
}
Note: When using nullable types, you'll need to use a cast or get it's value. See here.
Example:
int? n = ConvertStringToNumber("123");
int value = n.Value;
// or
int value = (int)n;
If you assigned a value to the Retval object AT THE FIRST TIME, then the value is valid in THAT area ONLY.
So, Retval is null when you return it.
since Int32.TryParse(TheString, out Retval) require int type not nullable
public int? ConvertStringToNumber(String TheString)
{
// Uninitialized
int Retval;
if (TheString.Length > 0)
{
// We have a valid string
if (Int32.TryParse(TheString, out Retval))
{
// We have a valid Number
return Retval;
}
}
// Return the number or null
return null;
}
Simple extension method to resolve your problem
using System;
namespace temp
{
class Program
{
static void Main(string[] args)
{
string valu = "";
Console.WriteLine(valu.ToInt32());
Console.ReadLine();
}
}
public static class MyExtentions
{
public static int ToInt32(this string s)
{
int x;
if (s != null)
{
if (s.Length > 1)
x = Convert.ToInt32(s);
else
x = 0;
}
else
{
x= 0;
}
return x;
}
}
}
int? x = ConvertStringToNumber("1");
int value = x.Value;
String to numeric conversion in c#

Datatypes in c#

I am in need of an integer data type which starts with 00 from 1 to 10 and 0 from 10 to 99.
Is there any data type in c#
Thank you very much....
You can use pretty much any integer type for that(int, uint, etc); the important part is how you format it. In this case:
string s = i.ToString("000");
The integer data type is just the value - leading zeros don't exist or not exist - simply that isn't the job of an integer.
You could always create a custom struct of course, taking the integer value in the constuctor (and maybe a custom conversion operator), overriding the ToString() method (and probably Equals, GetHashCode, etc).
Just for kicks:
public struct TriDigit : IComparable, IComparable<TriDigit>, IComparable<int>, IEquatable<TriDigit>, IEquatable<int>
{
private readonly int value;
public TriDigit(int value)
{
if (value < 0 || value > 999) throw new ArgumentOutOfRangeException("value");
this.value = value;
}
public override string ToString()
{
return value.ToString("000");
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj is TriDigit) return ((TriDigit)obj).value == value;
if (obj is int) return ((int)obj) == value;
return false;
}
public int CompareTo(object obj)
{
if (obj == null) return -1;
if(obj is TriDigit) return value.CompareTo(((TriDigit)obj).value);
if (obj is int) return value.CompareTo((int)obj);
return -1;
}
public override int GetHashCode()
{
return value;
}
public static explicit operator TriDigit(int value)
{
return new TriDigit(value);
}
public static implicit operator int(TriDigit value)
{
return value.value;
}
int IComparable<TriDigit>.CompareTo(TriDigit other)
{
return value.CompareTo(other.value);
}
int IComparable<int>.CompareTo(int other)
{
return value.CompareTo(other);
}
bool IEquatable<TriDigit>.Equals(TriDigit other)
{
return value == other.value;
}
bool IEquatable<int>.Equals(int other)
{
return value == other;
}
}
Sounds like you want a format string, not a data type.
Console.WriteLine("{0:D3}", i);
You can simply use int or if it must not be negative uint (unsigned integer). There are smaller data types, but for most applications they're not worth worrying about.
If you are saying that you need an integer with a legal range from 1 to 10, with an index that starts at zero, then the answer is no. You'll need to make your own an ADT for that.
It's formatting you want, not a new datatype. Read all about it here: MSDN's page on Custom Numeric Format Strings.
You can use PadLeft(int totalWidth, char paddingChar) like..
int myNumber=12
string myStringNumber = myNumber.ToString().PadLeft(3, '0');

Creating a generic method in C#

I am trying to combine a bunch of similar methods into a generic method. I have several methods that return the value of a querystring, or null if that querystring does not exist or is not in the correct format. This would be easy enough if all the types were natively nullable, but I have to use the nullable generic type for integers and dates.
Here's what I have now. However, it will pass back a 0 if a numeric value is invalid, and that unfortunately is a valid value in my scenarios. Can somebody help me out? Thanks!
public static T GetQueryString<T>(string key) where T : IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
What if you specified the default value to return, instead of using default(T)?
public static T GetQueryString<T>(string key, T defaultValue) {...}
It makes calling it easier too:
var intValue = GetQueryString("intParm", Int32.MinValue);
var strValue = GetQueryString("strParm", "");
var dtmValue = GetQueryString("dtmPatm", DateTime.Now); // eg use today's date if not specified
The downside being you need magic values to denote invalid/missing querystring values.
I know, I know, but...
public static bool TryGetQueryString<T>(string key, out T queryString)
What about this? Change the return type from T to Nullable<T>
public static Nullable<T> GetQueryString<T>(string key) where T : struct, IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
Convert.ChangeType() doesn't correctly handle nullable types or enumerations in .NET 2.0 BCL (I think it's fixed for BCL 4.0 though). Rather than make the outer implementation more complex, make the converter do more work for you. Here's an implementation I use:
public static class Converter
{
public static T ConvertTo<T>(object value)
{
return ConvertTo(value, default(T));
}
public static T ConvertTo<T>(object value, T defaultValue)
{
if (value == DBNull.Value)
{
return defaultValue;
}
return (T) ChangeType(value, typeof(T));
}
public static object ChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
throw new ArgumentNullException("conversionType");
}
// if it's not a nullable type, just pass through the parameters to Convert.ChangeType
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
// null input returns null output regardless of base type
if (value == null)
{
return null;
}
// it's a nullable type, and not null, which means it can be converted to its underlying type,
// so overwrite the passed-in conversion type with this underlying type
conversionType = Nullable.GetUnderlyingType(conversionType);
}
else if (conversionType.IsEnum)
{
// strings require Parse method
if (value is string)
{
return Enum.Parse(conversionType, (string) value);
}
// primitive types can be instantiated using ToObject
else if (value is int || value is uint || value is short || value is ushort ||
value is byte || value is sbyte || value is long || value is ulong)
{
return Enum.ToObject(conversionType, value);
}
else
{
throw new ArgumentException(String.Format("Value cannot be converted to {0} - current type is " +
"not supported for enum conversions.", conversionType.FullName));
}
}
return Convert.ChangeType(value, conversionType);
}
}
Then your implementation of GetQueryString<T> can be:
public static T GetQueryString<T>(string key)
{
T result = default(T);
string value = HttpContext.Current.Request.QueryString[key];
if (!String.IsNullOrEmpty(value))
{
try
{
result = Converter.ConvertTo<T>(value);
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
You can use sort of Maybe monad (though I'd prefer Jay's answer)
public class Maybe<T>
{
private readonly T _value;
public Maybe(T value)
{
_value = value;
IsNothing = false;
}
public Maybe()
{
IsNothing = true;
}
public bool IsNothing { get; private set; }
public T Value
{
get
{
if (IsNothing)
{
throw new InvalidOperationException("Value doesn't exist");
}
return _value;
}
}
public override bool Equals(object other)
{
if (IsNothing)
{
return (other == null);
}
if (other == null)
{
return false;
}
return _value.Equals(other);
}
public override int GetHashCode()
{
if (IsNothing)
{
return 0;
}
return _value.GetHashCode();
}
public override string ToString()
{
if (IsNothing)
{
return "";
}
return _value.ToString();
}
public static implicit operator Maybe<T>(T value)
{
return new Maybe<T>(value);
}
public static explicit operator T(Maybe<T> value)
{
return value.Value;
}
}
Your method would look like:
public static Maybe<T> GetQueryString<T>(string key) where T : IConvertible
{
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
return new Maybe<T>();
}
}
return new Maybe<T>();
}
I like to start with a class like this
class settings
{
public int X {get;set;}
public string Y { get; set; }
// repeat as necessary
public settings()
{
this.X = defaultForX;
this.Y = defaultForY;
// repeat ...
}
public void Parse(Uri uri)
{
// parse values from query string.
// if you need to distinguish from default vs. specified, add an appropriate property
}
This has worked well on 100's of projects. You can use one of the many other parsing solutions to parse values.

Categories