I guess that most of my frustration arises from the fact that workarounds such as the wrapping suggestion are necessary - and are not provided by the .NET API at all. Due to boxing and other similar features, I understand the making most primitive types map to a class rather than a struct would cause way too much implicit object bloat on the heap, and I appreciate the advantages that value types bring to the table, but I am still missing the reason why references to value types cannot hold NULL.
A very similar problem is encountered when dealing with Java primitives; however, Java provides the primitive wrapper classes that take care of instances in which I want to store a NULL value or take advantage of polymorphism and features reliant on Object derivations. Lastly, in response to another reply, I do realize that semantically, database NULL can mean something other than object NULL in some instances. However, in my situation, they mean the same thing -- "I do not know the value of this particular property or field." Thanks, joe -----Original Message----- From: Nick Wienholt [mailto:[EMAIL PROTECTED]] Sent: Sunday, June 09, 2002 2:22 AM To: [EMAIL PROTECTED] Subject: Re: [ADVANCED-DOTNET] Value type references (versus object references) Why not wrap the value types in a reference type (to support nulls), and provide an implicit conversion operator to the value type. There will be some small perf hits due to heap allocation and indirect access, but compared to cross-network DB access, they are unlikely to be significant. Example wrapper for ints below. Nick Sydney Deep .NET User Group www.sdnug.org public class ReferenceTypeInt { private int _i; public ReferenceTypeInt() { _i = 0; } public ReferenceTypeInt(int i) { _i = i; } public static implicit operator int(ReferenceTypeInt rti) { return rti._i; } public static implicit operator ReferenceTypeInt(int i) { return new ReferenceTypeInt(i); } } ----- Original Message ----- From: "Joe Duffy" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Saturday, June 08, 2002 5:48 AM Subject: [ADVANCED-DOTNET] Value type references (versus object references) > Perhaps I am asking this question out of ignorance, but why are value > type references handled differently than object references? I > understand that value type instantiations are held on the stack versus > the heap, but I must > be missing something about the way in which references to these > objects are > held (does each reference actually store a copy of the value since > they are > passed by value? if so, how does example #2 below work?). I suppose, > if I were not lazy, that I could examine the bytecode generated, but I > figured that somebody on this list could provide a good explanation. > > For instance, I am mostly annoyed by the handling of references to > NULL, which apparently value type references are incapable of. Let me > illustrate an example. > > Say I am instantiating an entity object that represents some logical > coupling of information stored in a relational database (common task, > right?). Now, assume that I have a date column in one of the tables in > the database that I am interested in representing within my object, > which happens to hold a NULL value for the entity that I am loading > (again, fairly > common). > > It seems that my options for representing a NULL DateTime are as > follows: > > 1) > DataReader reader = // ... > DateTime myDateColumn = // ... > // ... > if (reader["my_date_column"] is DBNull) { > myDateColumn = DateTime.MinValue; // or some other "special value" > indicating NULL } else { > myDateColumn = (DateTime)reader["my_date_column"]; > } > > One of the problems with this approach, is that wherever myDateColumn > is referenced, the code needs to know that DateTime.MinValue signifies > a NULL or empty value. Isn't this what NULL is for?!? > > 2) > DataReader reader = // ... > object myDateColumn = // ... > // ... > if (reader["my_date_column"] is DBNull) { > myDateColumn = null; > } else { > myDateColumn = reader["my_date_column"]; > } > > Obviously a better - and more true - representation of the value of > this field; however, then I lose type safety, am forced to recast > myDateColumn to > DateTime whenever I access it, etc., etc. This gets messy after a > while. > > Why is it that I cannot simply do: > 3) > DataReader reader = // ... > DateTime myDateColumn = // ... > // ... > if (reader["my_date_column"] is DBNull) { > myDateColumn = null; > } else { > myDateColumn = (DateTime)reader["my_date_column"]; > } > > In addition, I find it odd that, should I go with #1 above, the > following does not work: object xxx = > (myDateColumn.Equals(DateTime.MinValue) ? null : myDateColumn); > > ...while the following does: > object xxx = (myDateColumn.Equals(DateTime.MinValue) ? null : > (object)myDateColumn); > > Thanks in advance. > > Best Regards, > joe duffy > > You can read messages from the Advanced DOTNET archive, unsubscribe > from Advanced DOTNET, or > subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.
