Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have below C# code for parsing ... Do you think this is most optimize or I should use generic method or optimization required in these function itself?
public static bool GetDBBool(object value)
{
var result = false;
if (value != null && string.IsNullOrEmpty(value.ToString()) == false)
bool.TryParse(value.ToString(), out result);
return result;
}
public static int GetDBInt(object value)
{
var result = -999;
if (value != null && string.IsNullOrEmpty(value.ToString()) == false)
int.TryParse(value.ToString(), out result);
return result;
}
public static double GetDBDouble(object value)
{
var result = -999.00;
if (value != null && string.IsNullOrEmpty(value.ToString()) == false)
double.TryParse(value.ToString(), out result);
return result;
}
public static DateTime GetDBDate(object value)
{
var result = DateTime.Now;
if (value != null && string.IsNullOrEmpty(value.ToString()) == false)
DateTime.TryParse(value.ToString(), out result);
return result;
}
public static DateTime? GetDBNullableDate(object value)
{
DateTime date;
if (value != null && string.IsNullOrEmpty(value.ToString()) == false)
return DateTime.TryParse(value.ToString(), out date) ? date : (DateTime?)null;
else
return null;
}
There's nothing more you can optimize there. And I doubt that THIS is the slowest place in your program.
However your null-values are a bit odd. -999 for numbers? DateTime.Now for a DateTime? Are you sure that won't cause problems in other code? Those are pretty normal values which means that other code won't be able to distinguish whether you had a null, or an actual value. And this default value might be wrong for the other code.
If it was me, I'd use 0 for integer, and DateTime.MinValue for DateTime. Or better yet - just stick to nullables all the way.
"== false" is not very readable. Use ! instead.
If the "object value" is already of desired type (e.g. DateTime), it would be slower to convert it to string and then back again.
I would write instead
if (value is DateTime) return (DateTime)value;
I would not use var result = -999; as a return value.
If the conversion fails, you can either return Int32.MinValue (better than -999) or rather null.
Maybe also you would like to check for DBNull.Value? So first I would check for null and DBNull.Value, then "value is DateTime" check and the last thing would be DateTime.TryParse.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
so i have been trying to use both date time and int in the same if statement.
my code is like this:
public int wantedHours, wantedMinutes;
public int sysHour = System.DateTime.Now.Hour;
public int sysMinutes = System.DateTime.Now.Minute;
void Update()
{
if (sysHour == wantedHours && sysMinutes == sysMinutes)
{
sendTheNotif == true;
} else
{
sendTheNotif == false;
}
}
but it doesnt work. unity is giving me this error:
error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
Integers are set correctly.
You're using the equality operator in your if statements which is throwing the error
Suggest reading the microsoft doc
Try this
(note, you are checking equality between sysMinutes == sysMinutes in your if statement, is that what you're wanting to do?)
public int wantedHours, wantedMinutes;
public int sysHour = System.DateTime.Now.Hour;
public int sysMinutes = System.DateTime.Now.Minute;
void Update()
{
if (sysHour == wantedHours && sysMinutes == sysMinutes)
{
sendTheNotif = true;
} else
{
sendTheNotif = false;
}
}
In your code, you did not assign a value to wantedHours, and wantedMinutes.
also sysMinutes will always equal sysMinutes if there is no option to change its value in your code before comparison.
if (sysHour == wantedHours && sysMinutes == sysMinutes)
is the major problem. When you are comparing variables with == it means it should evaluate true if it is equal in type and value.
So wantedHours has no value assigned according to your code block above.
And sysMinutes is always equal to sysMinutes.
you have to use wantedTime instead
var sysTime = System.DateTime.Now;
If( (int)wantedTime.Subtract(sysTime).TotalMinutes ==0) sendTheNotif = true;
else sendTheNotif = false;
I've got an API that is passed a string that this particular system treats as NULL "1/1/1900". I've seen other users with a similar value inserted where null is expected in SQL. I tried this wacky setup:
static void Main(string[] args)
{
var input = "01/1/1900";//this does NOT evaluate to DBNull
var result = IsBasicallyNull(input);
}
private static bool IsBasicallyNull(string input)
{
if (String.IsNullOrWhiteSpace(input))
return true;
if (DBNull.Value.Equals(input))//THis doesn't work
return true;
//hack and slash
DateTime output;
var isValidDateTime = DateTime.TryParse(input, out output);
if (isValidDateTime)
{
if (output == DateTime.MinValue)
return true;
else if (output.Year.ToString() == "1900" && output.Day.ToString() == "1" && output.Month.ToString() == "1")
return true;
}
return false;
}
It's clear that DBNull.Value is not built to support this "1/1/1900" (MM/DD/YYY) oddity. Is it abnormal to get this value in SQL and it be treated as NULL? Do you know where this value comes from?
I had a simllar problem in the past. Some columns of type smalldatetime with no null values accepted were filled with the Minumum Value of a smalldatetime field. And this happen to be exactly 1/1/1900.
To consider these columns as they were null values I forced a piece of code like yours in this way
private static readonly DateTime minDB_smallDateTime = new DateTime(1900,1,1);
private static bool IsBasicallyNull(string input)
{
if (String.IsNullOrWhiteSpace(input))
return true;
DateTime output;
var isValidDateTime = DateTime.TryParse(input, out output);
if (isValidDateTime && output <= minDB_smallDateTime)
return true;
.... rest of checking code....
}
If you want to check wheter input is the string representation of a special date, you never can compare to DBNull.Value because it is something completely different. Try to compare against new DateTime( 1900, 1, 1 ).ToString() instead of.
I've got a Session that contains particular integer values, which are indexed with given controls. Normally, the following would work just fine:
int value;
int.TryParse(Session["Key"].ToString(), out value);
However, I do need to account for null. Where, if the string fails the default out would return a null. Except I noticed that int.TryParse doesn't work with:
int? value = null;
int.TryParse(Session["Key"].ToString(), out value);
So how can you try that parse, if fails it results in the null?
I found this question and the Microsoft Developer Network dictates:
When this method returns, contains the signed integer value
equivalent of the number contained in s, if the conversion succeeded,
or zero if the conversion failed. The conversion fails if the string
parameter is null or String.Empty, is not of the correct format, or
represents a number less than Min Value or greater than Max Value. This
parameter is passed uninitialized.
Which plainly states, if int.TryParse fails the integer will hold a value of zero. In the instance of my usage, zero could be a valid value. So I need null, any thoughts?
Sure; utilize the return value of int.TryParse (which returns if the conversion succeeded or not):
int? retValue = null;
int parsedValue = 0;
if (int.TryParse(Session["Key"].ToString(), out parsedValue))
retValue = parsedValue;
else
retValue = null;
return retValue;
A little verbose I'll admit, but you could wrap it in a function.
int tmp;
int? value = int.TryParse(Session["Key"].ToString(), out tmp) ? (int?)tmp : null;
The problem is the word "null." What does it mean? null could mean the value was indeterminable, an exception was thrown, simply that the value is null, or some other contextual meaning. Your question is a perfect example, because you, yourself, are arbitrarily stating that, in your opinion, null means the parsing of the string failed.
Microsoft's TryParse paradigm is great, but for limited usage. Consider these Scenarios:
string == "89"
string == null
string == "Hello World"
string == ""
string == "2147483650"
Yet, your only options are to assign an Integer or Null to your output, and to return true or false.
Assuming it worked, what are you going to do with that information? Something like this?
int? value = null;
if (int.TryParse(Session["Key"].ToString(), out value)) {
if (value == null)
// Handle "Appropriate" null
else
// Handle appropriate numeric value
}
else {
// Note: value == null here, and TryParse failed
// Handle null...
// What if the reason it failed was because the number was too big?
// What if the string was Empty and you wanted to do something special?
// What if the string was actually junk? Like "(423)322-9876" ?
// Long-Story Short: You don't know what to do here without more info.
}
Consider this NullableInt TryParse example:
public bool TryParseNullableInt(string input, out int? output)
{
int tempOutput;
output = null;
if (input == null) return true;
if (input == string.Empty) return true; // Would you rather this be 0?
if (!int.TryParse(input, out tempOutput))
return false; // What if string was "2147483650"... or "Twenty Three"?
output = tempOutput;
return true;
}
One solution is to use an enumeration TryParse instead of a boolean TryParse:
public ParseStatus TryParseNullableInt(string input, out int? output)
{
int tempInteger;
output = null;
if (input == null) return ParseStatus.Success;
if (input == string.Empty) { output = 0; return ParseStatus.Derived; }
if (!int.TryParse(input, out tempInteger)) {
if (ParseWords(input, out tempInteger)) { // "Twenty Three" = 23
output = tempInteger;
return ParseStatus.Derived;
}
long tempLong;
if (long.TryParse(input, out tempLong))
return ParseStatus.OutOfRange;
return ParseStatus.NotParsable;
}
output = tempInteger;
return ParseStatus.Success;
}
Another problem is the existence of the out variable. Your third option is to use a descriptive monad, something like this:
public Maybe<int?> TryParseNullableInt(string input)
{
if (input == null) return Maybe.Success(null);
if (input == string.Empty) { return Maybe.Derived(0); }
int tempInteger;
if (!int.TryParse(input, out tempInteger)) {
if (ParseWords(input, out tempInteger)) { // "Twenty Three" = 23
return Maybe.Derived(tempInteger);
}
long tempLong;
if (long.TryParse(input, out tempLong))
return Maybe.OutOfRange();
return Maybe.NotParsable();
}
return Maybe.Success(tempInteger);
}
You can use Monads as Single-Enumerable Values, or like so:
Maybe<int?> result = TryParseNullableInt("Hello");
if (result.HasValue) {
if (result.Status == ParseStatus.Success)
// Do something you want...
else if (result.Status == ParseStatus.Derived)
// Do something else... more carefully maybe?
}
else if (result.Status == ParseStatus.OutOfRange)
MessageUser("That number is too big or too small");
else if (result.Status == ParseStatus.NotParsable)
// Do something
With Monads, and possibly enumeration TryParses, you now have all the info you need from a descriptive return and nobody has to guess what null might mean.
In our application we work with DataTables a lot. This is dictated by the interface to a another system. Often a column in one of these DataTable's is in fact an enumeration, which is then of a Int16 datatype. Currently we use magic constants all over the place, but that isn't pretty. A real enum would be much better, but how can you write an elegant comparison? Especially considering that a DBNull is also sometimes a valid value.
Ideally we would write this:
if ( tbl.Rows[0]["EnumColumn"] == MyEnum.SomeValue )
// Do stuff
But, naturally, that will not work. The closest to what I can come is:
if ( tbl.Rows[0]["EnumColumn"] != DBNull.Value && Convert.ToInt32(tbl.Rows[0]["EnumColumn") == (int)MyEnum.SomeValue )
// DO stuff
Which looks plain ugly. Any ideas on how to make this prettier and easier to write?
It should be something like this:
tbl.Rows[0]["EnumColumn"] != DbNull.Value && Convert.ToInt32(tbl.Rows[0]["EnumColumn"]) == MyEnum.SomeValue
I would make a static method for it:
public enum TestEnum
{
A = 1,
B = 2
}
public static bool EqualsTestEnum(object value, TestEnum enumValue)
{
if (value == null || value == DBNull.Value)
{
return false;
}
int i;
if (int.TryParse(value.ToString(), out i))
{
return i == (int) enumValue;
}
return false;
}
intID1 = Int32.Parse(myValue.ToString());
intID2 = Convert.ToInt32(myValue);
Which one is better and why?
They are exactly the same, except that Convert.ToInt32(null) returns 0.
Convert.ToInt32 is defined as follows:
public static int ToInt32(String value) {
if (value == null)
return 0;
return Int32.Parse(value, CultureInfo.CurrentCulture);
}
Well, Reflector says...
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
public static int Parse(string s)
{
return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
So they're basically the same except that Convert.ToInt32() does an added null check.
It depends on what you mean by "better" because "better" is subjective.
For instance - code readability. Some people prefer to see "Convert" in their code; others prefer to see "Parse".
In terms of speed, they're also both roughly equal according to these benchmarks.
Or do you always wants a value returned? As others have mentioned, ConvertTo returns a 0 (zero) for null values whereas you don't get that option with Parse.