Comparison question

  • Thread starter Thread starter tshad
  • Start date Start date
T

tshad

I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied to
operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
tshad,

You want to do the following:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
// If the object is null, or db null, or the object is string, and it is
empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained like
this.

Hope this helps.
 
tshad said:
I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied to
operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom

The problem is in the order of evaluation. C# is evaluating this part
first:

dbObjectValue == DBNull.Value

This results in a boolean expression, which can't be compared to a
string. To make the ?: operator work you need to compare two like
types. This should work:

destination = ((dbObjectValue == DBNull.Value) ||
(dbObjectValue == string.Empty)) ?
decimal.MaxValue :
(decimal)dbObjectValue;

HTH!
Mike
 
Nicholas Paldino said:
tshad,

You want to do the following:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
// If the object is null, or db null, or the object is string, and it
is empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

Why would you check for both null and DBNull.Value?

if (dbObjectValue == null || dbObjectValue == DBNull.Value)

What is happening here is that this would either be a decimal being passed
in either from a decimal variable, textbox or a field from a database.

Thanks,

Tom
In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained
like this.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


tshad said:
I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref
decimal destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied
to operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
Mike Hofer said:
The problem is in the order of evaluation. C# is evaluating this part
first:

dbObjectValue == DBNull.Value

This results in a boolean expression, which can't be compared to a
string. To make the ?: operator work you need to compare two like
types. This should work:

destination = ((dbObjectValue == DBNull.Value) ||
(dbObjectValue == string.Empty)) ?
decimal.MaxValue :
(decimal)dbObjectValue;
I tried that and it gives me the following warning:

nullHandler.cs(24,54): warning CS0252: Possible unintended reference
comparison; to get a value comparison, cast the left hand side to type
'string'

Here is the statement

destination = ((dbObjectValue == DBNull.Value) || (dbObjectValue ==
string.Empty)) ? decimal.MaxValue : (decimal)dbObjectValue;

Thanks

Tom
 
tshad, if your database fields type is decimal (or money etc.) you "cant"
insert an empty string. so you dont have to check for that. and if
dbObjectValue's type can be a string, then (decimal)dbObjectValue will throw
an exception.
 
The Crow said:
tshad, if your database fields type is decimal (or money etc.) you "cant"
insert an empty string. so you dont have to check for that. and if
dbObjectValue's type can be a string, then (decimal)dbObjectValue will
throw an exception.

I understand that, but I am trying to do something like:

newObject.Salary = theSalary.Text

where theSalary is a textbox.

Normally, you would have a value in the box, but if the textbox was blank,
it will give you an error.

What I want to do is put a Null value into the database, but in my object I
am trying to put the decimal.MaxValue, as you did in your example before.

So if the value is null or empty, I make the decimal the MaxValue.

Thanks,

Tom
 
Tom,

I don't know what could be passed in. You are passing an object. In
reality, you should have overloads of the method which take specific types,
and call those, not take object. It certainly is possible that a null could
come into this function, depending on things such as data binding (the empty
string could be considered a null value in a textbox) the data adapter (what
if it uses Nullable types in 2.0), etc, etc.

In the end, I don't know what is coming into this object, so I pointed
out some things that you might not have considered.

You really should have type-specific overloads though.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

tshad said:
Nicholas Paldino said:
tshad,

You want to do the following:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
// If the object is null, or db null, or the object is string, and it
is empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

Why would you check for both null and DBNull.Value?

if (dbObjectValue == null || dbObjectValue == DBNull.Value)

What is happening here is that this would either be a decimal being passed
in either from a decimal variable, textbox or a field from a database.

Thanks,

Tom
In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained
like this.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


tshad said:
I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref
decimal destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied
to operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
tshad, since you are using my own codes, i think i can say, you have to use
GetValueFromDbObject only when you are getting the value from DataReader or
DataParameter.Value (for output parameters.) :) when getting the decimal
value from textbox, you probably will parse it to decimal
decimal salary = txtSalary.Text == String.Empty ? Decimal.MaxValue :
Decimal.Parse(txtSalary.Text);
and send to business object layer as decimal (as a method parameter or
entity property value.). to give you an idea, i have encapsulated this logic
to an "DecimalPicker" user web control. added javascript for validation and
Value Property. here is my code (my currency uses , as decimal seperator. so
you can modify):

<%@ Control Language="c#" AutoEventWireup="false"
Codebehind="DecimalPicker.ascx.cs"
Inherits="MyCompany.WebUI.WebUserControls.DecimalPicker"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<asp:TextBox ID="txtDecimal" Runat="server" CssClass="SaveFormTextBox" />
<asp:RequiredFieldValidator ID="valReqTxtDecimal" Runat="server"
Display="Dynamic" EnableViewState="False" ControlToValidate="txtDecimal">
<img src="/_MyCompanyLayout/images/warnimg.gif" alt="Please enter an valid
value." />
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="valRegExTxtDecimal" Runat="server"
Display="Static" ControlToValidate="txtDecimal" EnableViewState="False"
CssClass="Validator" EnableClientScript="True"
ValidationExpression="^(\d{1,3}(\.\d{3})*|(\d+))(\,\d{2})?$">
<img src="/_MyCompanyLayout/images/warnimg.gif" alt="Lütfen Geçerli Bir
E-Mail Giriniz." />
</asp:RegularExpressionValidator>


this is the code behind :


namespace Synapse.WebUI.WebUserControls

{

using System;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Text.RegularExpressions;

public class DecimalPicker : Synapse.WebUI.SynapseWebUserControlBase

{

protected System.Web.UI.WebControls.TextBox txtDecimal;

protected System.Web.UI.WebControls.RegularExpressionValidator
valRegExTxtDecimal;

protected System.Web.UI.WebControls.RequiredFieldValidator valReqTxtDecimal;

public bool Required

{

get

{

object o = ViewState["Required"];

if(o == null)

return true;

else

return (bool)o;

}

set

{

ViewState["Required"] = value;

}

}

public bool Enabled

{

get{return txtDecimal.Enabled;}

set{txtDecimal.Enabled = value;}

}

public decimal Value

{

get

{

return txtDecimal.Text == String.Empty ? Decimal.MaxValue :
Decimal.Parse(txtDecimal.Text);

}

set

{

txtDecimal.Text = value == Decimal.MaxValue ? String.Empty :
value.ToString();

}

}

#region Web Form Designer generated code

override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}


private void InitializeComponent()

{

}

#endregion

protected override void OnPreRender(EventArgs e)

{

valReqTxtDecimal.Enabled = Required;

base.OnPreRender (e);

}

}

}
 
Nicholas, IDataReader's indexer return object and IDbParameter.Value
property is an object. so i dont think you can use overloading. (method is
designed to take the value of database value's and convert it to a specific
type and contains some little logic doing this.)
 
the warning means, you cannot compare an object to a string using ==
operator. normally == operator compares object references. but string's
overload's this operator and gives different meaning. fallowing would be
right way doing that.

destination = ((dbObjectValue == DBNull.Value) ||
(dbObjectValue.ToString() ==
string.Empty)) ? decimal.MaxValue : (decimal)dbObjectValue;

you may wonder, why dbObjectValue == DBNull.Value worked? its just because
DBNull.Value designed as singleton pattern. this means that "the system has
only one instance of DBNull"
So == operator worked as expected.
 
Nicholas Paldino said:
Tom,

I don't know what could be passed in. You are passing an object. In
reality, you should have overloads of the method which take specific
types, and call those, not take object. It certainly is possible that a
null could come into this function, depending on things such as data
binding (the empty string could be considered a null value in a textbox)
the data adapter (what if it uses Nullable types in 2.0), etc, etc.

In the end, I don't know what is coming into this object, so I pointed
out some things that you might not have considered.

You really should have type-specific overloads though.

I agree and I do.

This was just an example.

But the problem is really a textbox. If you do:

myObject.Salary = Salary.Text

I am looking for a decimal value. But Salary.Text could also be empty.
This would give me an error as an empty string is not a decimal.

Typically, I would check this first and pass a 0 or maybe a -1 if it is
empty, but I am trying to do this inside my object.

I would have the same problem with the overloads for int or dates as well.

Tom
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

tshad said:
Nicholas Paldino said:
tshad,

You want to do the following:

public static void GetValueFromDbObject(object dbObjectValue, ref
decimal destination)
{
// If the object is null, or db null, or the object is string, and it
is empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

Why would you check for both null and DBNull.Value?

if (dbObjectValue == null || dbObjectValue == DBNull.Value)

What is happening here is that this would either be a decimal being
passed in either from a decimal variable, textbox or a field from a
database.

Thanks,

Tom
In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained
like this.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref
decimal destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue
: (decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied
to operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
Nicholas Paldino said:
tshad,

You want to do the following:

I tried your code, but got an error on:

// Check for a string.
string str = object as string;

The error was:

nullHandler.cs(34,24): error CS1525: Invalid expression term 'object'
nullHandler.cs(34,27): error CS1002: ; expected
nullHandler.cs(34,33): error CS1001: Identifier expected

Do you know what caused that?

Thanks,

Tom
public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
// If the object is null, or db null, or the object is string, and it
is empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained
like this.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


tshad said:
I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref
decimal destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied
to operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
Nicholas Paldino said:
tshad,

You want to do the following:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
// If the object is null, or db null, or the object is string, and it is
empty, then
// return the max value.
if (dbObjectValue == null || dbObjectValue == DBNull.Value)
{
// Return the max value.
return decimal.MaxValue;
}

// Check for a string.
string str = object as string;

This works really well if I change the above to: string str =
(string)dbObjectValue;

But it only works if I am using a textbox, such as:

myObject.Salary = salary.Text

but if I do:

myObject.Salary = 100;

or

decimal temp = 100;
myObject.Salary = temp;

I get an error at the line: string str = (string)dbObjectValue;

It gives me the error:

Specified Cast is not Valid.

I assume this is because I am passing an actual decimal and not a string to
be converted to decimal.

Is there a way to test to see if the object is string (text) or decimal
before trying to test it?

Thanks,

Tom
// If the string is not null, check for empty.
if (str != null)
{
// Trim the string.
str = str.Trim();

// If the string is empty, return the max value.
if (str == string.Empty)
{
// Return the max value.
return decimal.MaxValue;
}

// Set the object to the string.
dbObjectValue = str;
}

// Return the object, converted to a decimal.
return Convert.ToDecimal(dbObjectValue);
}

This checks to see if dbObjectValue is null as well, and it will also
trim the string, if it is a string, which is a little bit different than
what you had, but you might want to check (you can remove it if you have
specific meaning for strings of whitespace and the object is null).

In the end, this could have probably been done in one statement, but
this is a non-trivial piece of logic, and it is more easily maintained like
this.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


tshad said:
I tried to do this:

public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
destination = dbObjectValue == DBNull.Value || "" ? decimal.MaxValue :
(decimal)dbObjectValue;
}

Where I am just trying to say if dbObjectValue is either equal to a
DBNull.Value or "", make destination = decimal.MaxValue.

This gives me:

nullHandler.cs(24,18): error CS0019: Operator '||' cannot be applied to
operands of type 'bool' and 'string'

How would I change that statement to do what I am trying to do?

I am trying to move the value passed (dbObjectValue) into destination,
unless = Null or empty string (as this may come from a blank textbox).

Thanks,

Tom
 
tshad said:
This works really well if I change the above to: string str =
(string)dbObjectValue;

<snip>

As you've seen, that fails if dbObjectValue is a string. If you change
Nick's example slightly less though, to:

string str = dbObjectValue as string;

then it will work, because his next line was:

if (str != null)

The "as" operator is like casting, but the result is null if the type
isn't the one you're trying to use it as. (Casting also potentially
performs extra conversions which as doesn't, but that's not relevant
here.)
 
Jon Skeet said:
<snip>

As you've seen, that fails if dbObjectValue is a string. If you change
Nick's example slightly less though, to:

string str = dbObjectValue as string;

then it will work, because his next line was:

if (str != null)

The "as" operator is like casting, but the result is null if the type
isn't the one you're trying to use it as. (Casting also potentially
performs extra conversions which as doesn't, but that's not relevant
here.)

You're right (as was Nick). It works great.

I was confused on the "as". I thought maybe he made a mistake and was
thinking VB.Net. Also, he used object instead of dbObjectValue I wasn't
sure if that was a mistake or I didn't understand what he was doing.

So now I can handle the Set, but still have a problem with the get, which is
going to be a little more difficult to deal with.

It almost works. As a matter of fact it works for all the situations I have
tested for except if the TextBox was blank. The problem is when I did a Set
and changed the value to decimal.MaxValue (in the decimal case). I have no
way to know if the value was set because the original value was DBNull.Value
or blank. Both cases I set to MaxValue. With the Get I don't know what to
set the value to. If I set it to a DBNull.Value and it is a TextBox, I get
an error.

Here is the code to return the Null if the value was set to MaxValue.

public static object SetDbObjectValueFromValue(decimal sourceValue, ref
object dbObjectValue)
{
if(sourceValue == decimal.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
return dbObjectValue;
}

The Get/Set code is:

public object Salary
{
get
{
object value = null;
return NullHandler.SetDbObjectValueFromValue(salary,ref value);
}
set
{
NullHandler.GetValueFromDbObject(value,ref salary);
}
}

The code to get the value for a TextBox is:

salary.Text = newTestNulls.Salary

This will get me the error: "Cast from type 'DBNull' to type 'String' is
not valid."

The only way I can see to solve the problem would be to set the Class
variable to MaxValue if DBNull and MaxValue-1 if blank.

Thanks,

Tom
 
if you use object type for Salary, why dont you use DBNull.Value if value is
DBNull and use Decimal.MaxValue ? i think you are very very confused.
 
The Crow said:
if you use object type for Salary, why dont you use DBNull.Value if value is
DBNull and use Decimal.MaxValue ? i think you are very very confused.

Probably true.

I am not sure what you are saying here.

Salary (object) is my property to allow me to access salary (decimal).

Can you set the value of Salary?

I thought properties were only a way to access my private variables, but not
really a variable itself. I could be wrong here.

To access salary, I would do myObject.Salary - where Salary is just function
to get and set salary (I thought.

Tom
 
you sure right about what properties are. but you should use (in my opinion)
decimal as data type of your property. if you will use object as datatype,
then dont bother with DBNull. just assign dbnull directly. my intention
using Decimal.MaxValue was because decimal type cant hold null values...

you shouldnt assign a string to salary as database persistence will be a
disaster because your column type is decimal (or probably money in sql
server.).

have you inspected my decimalpicker example?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

arithmetic overflow 3
Class method doesn't seem to work 2
String and null vs DBNULL 7
delegate usage? 7
Casting in a generic function 3
how to save my class in settings 1
Override the property 5
trinary statement 14

Back
Top