Can a Generic Method handle both Reference and Nullable Value types?

Default(T) : (T) dr.GetValue(ordinal); } This way, if T is a nullable int or any other nullable value type, it will in fact return null. If it's a regular datatype, it will just return the default value for that type.

1 Its is very bad solution. If is in datarecord NULL value, you does not want a default value of int. The NULL and ZERO are different values.

– TcKs Nov 19 '08 at 20:53 2 IF the value in the database is nullable, then the T would be a Nullable in which case NULL is the default value that would be returned. – BFree Nov 19 '08 at 20:54 1 If so, why do this extension method, if you can use simply "drordinal as int? "?

– TcKs Nov 19 '08 at 20:57 1 drordinal will throw an exception if it's DBNull. – Adam Lassek Nov 19 '08 at 21:40 1 @juan That seems like a pretty superfluous error. I disagree with FxCop on this one -- explicitly stating the type of a generic method is not a bad thing.

– Adam Lassek Nov 19 '087 at 20:01.

I don't think you can implement this with a single function. If C# supported overloading based on return type, you might be able to, but even then I would recommend against doing so. You should be able to accomplish the same thing by not using nullable data types and return either an actual value or null, as suggested by BFree.

Actually, you can have two overloaded methods that only differ in return types. This is legit syntax: public string Method() { return ""; } public int Method() { return 0; } – BFree Nov 19 '08 at 21:12 @BFree : Type 'xyz' already defines a member called 'Method' with the same parameter types. – David B Nov 19 '08 at 21:16 @BFree: I just tried your exact code and got the following error: Type 'Program1' already defines a member called 'Method' with the same parameter types.

– Scott Dorman Nov 19 '08 at 21:18 The parameter types are the same, but the return types are different, and that is legit syntax. Try it out.... – BFree Nov 19 '08 at 21:20 OK, I stand corrected. For some reason I was convinced you CAN do that.

Mah bad.... – BFree Nov 19 '08 at 21:21.

This is pretty much the same as BFree's answer. The sample usage is helpful. – David B Nov 19 '08 at 21:31.

I can't understand why the need to over complicate this whole process. Why not keep it nice and simple and use the following lines of code: For value types where null is valid use int? INullable = drordinal as int?

;. For value types where null is invalid use int iNonNullable = drordinal as int? Default(int);.

For reference types use string sValue = drordinal as string;. For anyone who thinks that the code won't work and that drordinal will throw an exception for DBNull here is an example method that once given a valid connection string will prove the concept. Private void Test() { int?

ITestA; int? ITestB; int iTestC; string sTestA; string sTestB; //Create connection using (SqlConnection oConnection = new SqlConnection(@"")) { //Open connection oConnection.Open(); //Create command using (SqlCommand oCommand = oConnection.CreateCommand()) { //Set command text oCommand. CommandText = "SELECT null, 1, null, null, '1'"; //Create reader using (SqlDataReader oReader = oCommand.ExecuteReader()) { //Read the data oReader.Read(); //Set the values iTestA = oReader0 as int?

; iTestB = oReader1 as int? ; iTestC = oReader2 as int? -1; sTestA = oReader3 as string; sTestB = oReader4 as string; } } } }.

As I already explained to BFree in the comments, drordinal throws an exception if it's DBNull. Your example won't work. – Adam Lassek May 17 '10 at 23:46 @Adam Lassek - I don't know why you think my code won't work, have you tried it?

I have it running on production systems, please actually check the code before down-voting. I think most noobs could tell you that drordinal won't throw an exception if the value is DBNull. – Stevo3000 May 18 '10 at 8:55 what framework version?

At the time I wrote this question, I was using 3.5 and it definitely threw an exception if the field was DBNull. – Adam Lassek May 27 '10 at 1:53 stackoverflow. Com/questions/1855556/datareader-best-practices/… – Adam Lassek May 27 '10 at 1:56 @Adam Lassek - Well I've tested it on both .

NET 2.0 and . NET 3.5 (repeatedly) and it works flawlessly. You will NOT get an exception reading DBNull from a DataReader into a compatible object type or by using the as keyword to cast as type or set null.

I suggest you make a dummy app and run the method above to prove this. You can also use object oObject = oReader0; to prove that you can access a DBNull object directly from the reader. – Stevo3000 May 28 '10 at 7:59.

The Nullable structure is only for Value types, because reference types are nullable anyway...

Which is why I can't make this return Nullable, which is why I asked the question. – Adam Lassek Nov 19 '08 at 20:49.

You can't do it with one method but you do it with three: public static T GetData(this IDataReader reader, Func getFunc, int index) { if (!reader. IsClosed) { return getFunc(index); } throw new ArgumentException("Reader is closed. ", "reader"); } public static T GetDataNullableRef(this IDataReader reader, Func getFunc, int index) where T : class { if (!reader.

IsClosed) { return reader. IsDBNull(index)? Null : getFunc(index); } throw new ArgumentException("Reader is closed.", "reader"); } public static T?

GetDataNullableValue(this IDataReader reader, Func getFunc, int index) where T : struct { if (!reader. IsClosed) { return reader. IsDBNull(index)?

(T? )null : getFunc(index); } throw new ArgumentException("Reader is closed.", "reader"); } Then to use it you would do: private static Whatever CreateObject(IDataReader reader) { Int32? Id = reader.

GetDataNullableValue(reader. GetInt32, 0); string name = reader. GetDataNullableRef(reader.

GetString, 1); Int32 x = reader. GetData(reader. GetInt32, 2); }.

Public static T Get(this IDataRecord rec, Func GetValue, int ordinal) { return rec. IsDBNull(ordinal)? Default(T) : GetValue(ordinal); } or more performant public static T Get(this IDataRecord rec, Func GetValue, int ordinal) { return rec.

IsDBNull(ordinal)? Default(T) : GetValue(rec, ordinal); } public static Func GetInt32 = (rec, i) => rec. GetInt32(i); public static Func GetBool = (rec, i) => rec.

GetBoolean(i); public static Func GetString = (rec, i) => rec. GetString(i); and use it like this rec. Get(GetString, index); rec.

Get(GetInt32, index).

You've managed to implement a generic function without realizing the slightest benefit from it. Not having to write a separate function for each type is the whole point of generics, and the reason for this question being posted. – Adam Lassek Jun 26 '09 at 20:03 Maybe, but the difference from your solution is that you have only one method where you check for nullability and avoid casting which may be costly if you have really large datasets.

– SeeR Jun 26 '09 at 21:15 Also comparing to BFree solution you avoid boxing – SeeR Jun 26 '09 at 21:27.

String someText = GetSomeText(); record"Description" = someText.ToDbString(); // ........ public static class StringExtensionHelper { public static object ToDbString( this string text ) { object ret = null! = text? Text : DBNull.

Value return ret; } } EDIT: You can ( or you should ) have a "ToDbInt32, ToDbBool, etc..." extension methods for other primitive types ofcourse. EDIT 2: You can also extend the base class "object" with "ToDbValue". Public static class StringExtensionHelper { public static object ToDbValue( this object value ) { object ret = object.

ReferenceEquals( value, null )? (object)DBNull. Value : value; return ret; } }.

I could, but the whole point of this generics exercise is to avoid writing a separate method for each datatype. And I don't see how your example is even pertinent... I'm extending IDataRecord to null check data taken from the datastore. – Adam Lassek Nov 19 '08 at 20:54 If you want check values from record, you can use "as" keyword, which do what you want.

If is in record DbNull, then null will be returned. Otherwise the will be returned "int" as "Nullable". No special method is required.

– TcKs Nov 19 '08 at 21:03 You should not extend object with an extension method as it won't be available in all languages, like VB. NET – Scott Dorman Nov 19 '08 at 21:08 @Scott Dorman: Yes, but only if you need CLS compliance. .

NET has a lot of languages, be care about all of them is IMHO not good way. – TcKs Nov 19 '08 at 21:17.

Jul 10 at 11:38How do I render a jQuery. Tmpl Template to a String?

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions