Wrox Programmer Forums
Go Back   Wrox Programmer Forums > C# and C > C# 2005 > C# 2005
|
C# 2005 For discussion of Visual C# 2005.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# 2005 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old September 20th, 2007, 10:16 AM
Registered User
 
Join Date: Sep 2007
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Reducing code lines with suitable method

I have some code that reads data from a datareader to my customer class. I would like to simplify the repeated lines of code into one method. Some data elements are strings whilst others are decimal values.

If I write a method that takes in 2 objects (e.g. the datareader element and the customer property) how do I check which conversion (ToString or ToDecimal) is required?

Here is the code in its current form:

        private void GatherCustomerData(Customer cust, SqlDataReader rs)
        {
            if (rs["Title"] != DBNull.Value)
            {
                cust.Title = Convert.ToString(rs["Title"]);
            }

            if (rs["Surname"] != DBNull.Value)
            {
                cust.Surname = Convert.ToString(rs["Surname"]);
            }

            if (rs["BankBalance"] != DBNull.Value)
            {
                cust.BankBalance= Convert.ToDecimal(rs["BankBalance"]);
            }

            if (rs["DebtTotal"] != DBNull.Value)
            {
                cust.TotalDebts = Convert.ToDecimal(rs["DebtTotal"]);
            }
        }
 
Old September 20th, 2007, 10:36 AM
Wrox Author
 
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
Send a message via AIM to dparsons
Default

I wrote a class that uses Reflection to do this type of thing but it by no means will reduce the number of lines. The class itself is 300+ lines and there is a certain level of complexity involved in using it.

If you would like to see it send me an email and I will show you a copy of the class since its quite extensive to be posting here in the forum.




================================================== =========
Read this if you want to know how to get a correct reply for your question:
http://www.catb.org/~esr/faqs/smart-questions.html
================================================== =========
Technical Editor for:
Professional Search Engine Optimization with ASP.NET

Professional IIS 7 and ASP.NET Integrated Programming

================================================== =========
 
Old September 20th, 2007, 10:48 AM
Registered User
 
Join Date: Sep 2007
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I'm sure the above code should be achievable in a method (or class) with only a few lines. I can do it in VB but not sure on the C# syntax.

I'm thinking along the following lines

private void NewMethodName(object dataValue, object customerProperty)
{
//Logic if dataValue is not null then
// assign the dataValue to the customer property
//If CustomerProperty is String
// convert to string and assign
//if customerProperty is Decimal
// convert to decimal and assign
}

and in the calling function (code in my last post) would
contain something like this

NewMethodName(rs["Surname"], cust.Surname);
NewMethodName(rs["BankAmount"], cust.Amount);
 
Old September 20th, 2007, 11:04 AM
Wrox Author
 
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
Send a message via AIM to dparsons
Default

You could do something like this:

private void NewMethodName(object dataValue, TypeCode typ)
{
   switch(typ)
   {
     case TypeCode.String:
     break;
     case TypeCode.Int32:
     break;
   }
}

NewMethodName(rs["Surname"], cust.Surname.GetTypeCode());

================================================== =========
Read this if you want to know how to get a correct reply for your question:
http://www.catb.org/~esr/faqs/smart-questions.html
================================================== =========
Technical Editor for:
Professional Search Engine Optimization with ASP.NET

Professional IIS 7 and ASP.NET Integrated Programming

================================================== =========
 
Old September 21st, 2007, 08:48 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Quote:
quote:Originally posted by john316
 NewMethodName(rs["Surname"], cust.Surname);
NewMethodName(rs["BankAmount"], cust.Amount);
Unfortunately you can't do this the way you want. Passing a simple type property to a method simply passes the value. You can't use ref or out parameters either because of the way properties work. A property is really two methods (the Get and Set) so you can't technically pass them as references even if the type exposed would normally be a reference type (non-primitive).

Doug's suggestion of a class that does this with reflection, to me, seems like major overkill. Reflection is slower and excessive for doing something that can be achieved in a few small methods.

Your problem is a typical problem people deal with when creating the object-to-relational plumbing of a data driven app. I usually do this kind of thing with a few helper methods in a base data access layer class that I extend for each of the specific data access classes.

The methods are usually something like this:
Code:
protected string GetString(object value){
   //Test for DBNull here
   //return appropriate value (value.ToString(), string.Empty, etc.)
}
Often, I'll overload those methods to support default values:
Code:
protected string GetString(object value, string defaultValue){
   //Test for DBNull here, return default if null
   //return value.ToString()
}
protected string GetString(object value){
   return GetString(value, string.Empty);
}
Create these helper methods for all data types you need. You may find there aren't as many as you'd think. For numeric types you can use generics for a single set of methods that handles all those types, for example:
Code:
protected T GetNumeric<T>(object value, T defaultValue){
   if(value is DBNull) return defaultValue;
   return (T)value; //cast value to generic type
}
protected T GetNumeric<T>(object value){
   return GetNumeric<T>(value, 0);
}
Although I haven't tried it, you could probably get away with a single generic method for most types, although this limits the ability to create a single parameter "default return" method:
Code:
protected T GetDbValue<T>(object value, T defaultValue){
   if(value is DBNull) return defaultValue;
   return (T)value; //cast value to generic type
}
//protected T GetDbValue<T>(object value){
//   return GetDbValue<T>(value, ???); //Can't really do this
//}
The dissadvantage of the generic approach is that you calls to the methods are more verbose. You may be better to create some methods for the discreet types you know you need to deal with (strings, numerics, etc.) but also have a generic method for those other cases. This will provide the flexibility and simplicity in the helper methods while keeping your consuming code cleaner.

-Peter
 
Old September 21st, 2007, 10:05 AM
Wrox Author
 
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
Send a message via AIM to dparsons
Default

Agreed Reflection is slower for something this simple but, i suppose, it depends on your ultimate intent.

The class that I wrote is part of a huge application that has alot of custom objects so, instead of writing methods that populated these objects from a dataset, i wrote this class in such a way that it will take any object and any dataset and bind the data to the object.

Reflection is used to get all the properties of the given object and then I get the ordinal location of the value related to x property of the object. For my purpose, all i care about is getting an object back that is populated with x data regardless of the object and dataset that I pass into it. Obviously, if the dataset does not match the object, an empty object is returned.

So yes, for this particular secnario this class may not be ideal if this is soemthing the OP will only be doing once and awhile.

Very nice examples btw Peter ^^

================================================== =========
Read this if you want to know how to get a correct reply for your question:
http://www.catb.org/~esr/faqs/smart-questions.html
================================================== =========
Technical Editor for:
Professional Search Engine Optimization with ASP.NET

Professional IIS 7 and ASP.NET Integrated Programming

================================================== =========
 
Old September 21st, 2007, 10:34 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Doug,

I'm curious how you implemented this. I have thought about a similar type of implementation but haven't done anything with it. I thought of using some custom attributes to decorate the properties with the field names they map to and such. Of course, I just need to wait a bit longer and use the .net 3.5 entity framework and Linq to do it for me.

-Peter
 
Old September 21st, 2007, 10:43 AM
Wrox Author
 
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
Send a message via AIM to dparsons
Default

Peter,
   Your gmail account just grew by about 7K. ;]

================================================== =========
Read this if you want to know how to get a correct reply for your question:
http://www.catb.org/~esr/faqs/smart-questions.html
================================================== =========
Technical Editor for:
Professional Search Engine Optimization with ASP.NET

Professional IIS 7 and ASP.NET Integrated Programming

================================================== =========





Similar Threads
Thread Thread Starter Forum Replies Last Post
Reducing the number of Pages in a Report derekdeben Access 1 January 23rd, 2007 05:58 PM
Add few Lines of code to All new aspx pages. gadhiav ASP.NET 1.0 and 1.1 Professional 3 October 19th, 2005 02:33 PM
reducing the size of swf files Adam H-W Flash (all versions) 7 December 31st, 2004 07:50 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.