CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Grant Killian's Blog

No, this has nothing to do with beer -- but maybe it should?

March 2004 - Posts

  • objBag.Remove( objCat )

    Geoff Snowman makes it official . . . Wintellect big-wig John Robbins will be speaking at WeProgram.Net April 8th. We'll also be giving away a free pass to the Devscovery conference in late April, so don't miss this one! 

    There might be a surprise speaker at this WeProgram.Net meeting, too; I can't say more right now.

    Happy .Netting!

  • .Net Everywhere

    I found this precious gem nestled in the comments to Darrell Norton's post about his and Paul's highway interaction with a Java guy.

    I assume it's Greg “Am I the only one who missed PDC 2003“ Robinson's vehicle, in which case that means two things:

    1. Greg must really know his stuff (to put that on your license plate means you have to walk the walk!); I plan to start following his weblog.
    2. And the personalized plate I want, “CLRRULZ“, might still be available!

    By the way, Greg isn't the only one who missed PDC 2003; I passed on it too.

    I can see all this spiraling out of control -- creating a frantic rush to include .Net in some interesting way and capturing it in a photograph.  Photoshop NOT allowed (Darrell!).  Maybe WeProgram.Net should sponsor a contest . . .

    Happy .Netting!

  • If at first you don't succeed, don't admit you tried?

    What happened to “software as a service?”  CNET has an article about the struggles of MS Passport and the whole “.Net My Services” initiative.  A few years back, I recall hearing how we all would be downloading MS Office apps and renting application functionality a month or year at a time (instead of installing and licensing it on our own computer the conventional way).  It would be integrated via Passport and life would be good.  While .Net My Services was all about identity-based web services for cross-application convenience, and “Software as a Service” is more about sales strategy, I see the two issues linked together.

    The software as a service idea may be a bit ahead of its time (or, perhaps, not such a good idea after all).  I don't have a strong opinion either way, but I'm relieved to see Passport isn't as pervasive as Microsoft envisioned.  Rushing to be the first into the “store everybody's credit card and personal information in one spot“ space is not something to take lightly, and I don't know that the Liberty Alliance is in a better position to lead the charge.  You don't want to be the group that gets its wrong -- too much is at stake.  I don't even know that the goal is worth achieving, to be frank.  The fact that Microsoft is backing off of Passport is not bad news.

    While I applaud Microsoft for taking the risk, I also applaud them for having the strength to back off.  We shouldn't live by the credo:  If at first you don't succeed, don't admit you tried.  I feel the same about all the Windows and Microsoft security vulnerabilities that are broadcast . . . don't think that RedHat or other companies are free of these kind of problems -- Microsoft has a standard mechanism for broadcasting and communicating the problems (and the solutions!); at least they have the courage to announce the problem and move on; Microsoft's enormous visibility makes them an attractive target to the black-hat hacker community.

    Happy .Netting!

  • User Groups and getting connected

    I recommend that .Net developers everywhere check out their local user groups.  If there isn't one around you, start one up.  You don't need 100+ people to run a successful group; in the first year, WeProgram.Net has gotten between 10 and 30 people to the monthly meetings.  With the support of INETA, a user group is not the daunting task you might think it is.  You do need a couple (we've got 3 at WeProgram.Net: Mark and Darrell along with me) committed individuals to keep the gears running, but once you get started, you'll find the group takes on a momentum of its own.

    For example, WeProgram.Net has partnered with many technical book publishers for giveaways at meetings; there are component vendors who contact us about making presentations and giving away free copies of their components; late last year we learned that a leading figure at Wintellect worked in our area and we've forged a close partnership with Wintellect as a result.  A user group can really take on a life of its own!  If you need some pointers, just let me know and I'd be happy to help (INETA does a fine job of this too!).

    If user group material is too basic for you (as some friends have complained to me in other cities), don't discount the networking opportunities that occur when you hang out, eat some pizza, and check out the latest developments in the programming community.  I think WeProgram.Net might err on the side of too advanced in some cases!

    There are other ways to connect with other developers.  Go to a conference.  They all aren't $2,000 bombs to drop on your managers.  Devscovery is a steal at under $1,000 (coming to DC late in April!).  Check out a newsgroup -- it's a very passive way to stay abreast of the challenges and solutions circulating in the .Net world.  Heck, even subscribing to a magazine might surprise you in what you can learn.  Besides a good article, I even know some technical types who subscribe to the magazines (like MSDN, CODE, etc.) just to see who is launching ad campaigns and what marketing direction others are taking (based on the advertisements in the magazines).

    There was a time when mixing and learning with other developers was much tougher; now it isn't!  INETA lists the member groups, so check out the list and get connected!

    Happy .Netting!

  • DataReader to DataTable sample code

    Carlos, in a comment on my blog, requested the code I used in this post to efficiently convert a DataReader into a DataTable (it's inspired by Roy Osherove's post here and the comments to that post).  For posterity, I'm including the following example of how to extend the base DBDataAdapter class for fun and profit . . . I've formatted the most important code in bold.  This was a useful intermediary between a data access layer that delivered DataReaders and a business layer that worked with DataTables and DataSets.

    //CustomAdapter Class
    using System;
    using System.Data;

    namespace TheApplication.DataObjects
    {
     public class CustomAdapter : System.Data.Common.DbDataAdapter
     {
      public int FillFromReader(DataTable dataTable, IDataReader dataReader)
      {
       return this.Fill( dataTable, dataReader );
      }

      protected override System.Data.Common.RowUpdatedEventArgs CreateRowUpdatedEvent( DataRow a, IDbCommand b, StatementType c, System.Data.Common.DataTableMapping d )
      {
       return ( System.Data.Common.RowUpdatedEventArgs )new EventArgs();
      }
        
      protected override System.Data.Common.RowUpdatingEventArgs CreateRowUpdatingEvent( DataRow a, IDbCommand b, StatementType c, System.Data.Common.DataTableMapping d )
      {
       return ( System.Data.Common.RowUpdatingEventArgs )new EventArgs();
      }
      
      protected override void OnRowUpdated( System.Data.Common.RowUpdatedEventArgs value )
      {

      }
      protected override void OnRowUpdating( System.Data.Common.RowUpdatingEventArgs value )
      {

      } 
     }
    }

    And here is a plain vanilla sample usage of the class:

    public static DataTable getDataTable( string sql )
      {
       DataTable dtOut = new DataTable();
       OdbcConnection cn = new OdbcConnection( ConnString() );
       cn.Open();
       OdbcCommand cmd = new OdbcCommand( sql, cn );
       IDataReader dr = cmd.ExecuteReader();

       CustomAdapter da = new CustomAdapter();
       da.FillFromReader( dtOut, dr ); //converts a datareader into a datatable
       cn.Close();
       return dtOut;
      }

    Happy .Netting!

  • WebSuperGoo can't be blamed for my walking into the women's restroom . . .

    . . . I was wrestling with a customer's FTP problem while walking through the airport and those darn bathroom entrances look so similiar . . . I knew something was wrong when all I saw were stalls and no urinals, but my brain was, apparently, doing some asynchronous work and it wasn't until the nearest stall door opened and a grandmotherly lady exclaimed “Oh, my.” that it all became clear to me.

    I did a quick turn around and exited before any serious damage was done, but it was embarrasing.  They should color code the floors (pink versus blue?) -- instead of just labeling the entrances “Women“ and “Men.”  The perfumy smell should have signalled me, too, but I was lost in thought. 

    The good news is I resolved the customer's problem and, with the help of WebSuperGoo's upload component, the issue is pretty much closed.  While I'm on the topic, the WebSuperGoo upload product took about 5 minutes to use in place of the conventional Upload logic with ASP.Net (that 5 mins includes downloading and installation the component -- everything).   The only problem I had was on the first installation I ran, it popped up a “insufficient security permissions” dialogue about a Config.MSI file.  I clicked “Try Again” and it ran without issue.  For a bit more on ASP.Net file uploads, see this earlier post and the comments; that's where I was introduced to WebSuperGoo.

    Keep your head up in those airports!

  • CommandBuilder Revisited

    We just wrapped up teaching our sessions on ADO.net in ODU's ITPro curriculum, and [yet again] the subject of the CommandBuilder came up.  While I first mentioned this in this post from 2003, it's a topic of confusion and warrants revisiting.

    Paul Laudeman first pointed out this MSDN article on Weaning Developers from the CommandBuilder last year; Paul was in the midst of a data-access architecture debate at one of his client's sites and we were going back and forth about how to address the issue.  I think Darrell Norton, Mark DiGiovanni, and Brendan Thompkins (among others) were included in this email thread from Spring 2003.  The moral of the email-story is that even if you provide backup and documentation supporting your informed opinion, customers are under no obligation to take the advice!  If I'm a painter and somebody pays me to paint their house black, once I've confirmed that's what they really want to do and I've explained how uncomfortable a black painted house may be, my job is still to paint; how badly do I need the painting business?  But I digress . . .

    Bottom line: the CommandBuilder is effective only with a very simple SELECT query.  See the full article for some alternatives. 

    Also, rumours abound that Whidbey (now scheduled for a 2005 release) improves DataAdapter behaviour and addresses some of the CommandBuilder shortcomings.  I haven't had time to drink much Whidbey kool-aid, so I can't speak from experience.

  • Overflows, C# and VB.Net, and IL

    Students frequently ask, "What are the differences between C# and VB.Net?"  One of the first things we cover in our beginning .Net classes is how .Net languages like VB.Net and C# both produce MSIL (Microsoft Intermediate Language); IL, in turn, is used to produce the machine instructions for your program.  Most agree that the .Net language you use is more a matter of preference than anything else -- in the end, it all produces Intermediate Language code. 

    The catch is that IL isn't exactly the same between C# and VB.Net -- each compiler can emit different IL instructions.  We can leverage IL to get insight into the subtle differences between VB.Net and C#. 

    Let's take a simple Windows application with a button and textbox on it; we'll add a single event handler for the button.Click event like this:
    VB (With Option Strict On)
    Line 1) dim b as byte = byte.Parse( Textbox1.Text ) 'convert byte from Textbox's string
    Line 2) b = b + byte.Parse( "200" ) 'literals are integers and Option Strict forces our explicit conversion here
    Line 3) MessageBox.Show( b.ToString() )

    C#
    Line 1) byte b = byte.Parse( Textbox1.Text ); //convert byte from Textbox's string
    Line 2) b += 200;
    Line 3) MessageBox.Show( b.ToString() );

    If you run this code and type the number 1 into the textbox and click your button, you'll get "201" displayed in the MessageBox for VB.Net and C#.  If you type a number large enough so we exceed the capacity of a byte in line 2, say "100", you'll get an exception in VB and you'll get "44" displayed in the C# MessageBox.

    This is because by default, C# doesn't check for mathematical overflows (overflows occur when you exceed the range of a type -- a byte can contain values ranging 0-255).  So when we try to squeeze a 300 value into our byte, the first 255 is discarded leaving us with 44.  This can actually be useful; in cases where you're computing a checksum or hash based on a class, this behaviour can be important.

    Digging into this example further, C# offers the checked and unchecked keywords that will set the execution context of the C# compiler.  If we typed:
    checked
    {
        byte b = byte.Parse( Textbox1.Text );
        b+=200;
        MessageBox.Show( b.ToString() );
    }

    We would force C# overflow checking for this particular block of code and raise an Overflow exception if we type "100" into our Textbox. unchecked does the opposite.  C# also offers a project compiler setting from the Project Property Page (right click on the Project in Solution Explorer); it's in Configuration Properties->Build and look at the Code Generation section.  We can toggle this behaviour on or off via the "Check for Arithmetic Overflow/Underflow" option.

    I know some people like to switch this to "True" for C# projects while you're developing the program, and then switch it to "False" once you release the program -- they want to boost the performance of their application when they release it.  I don't take such a blanket approach; instead, I would pay attention to your C# code for places where arithmetic overflow is a danger and plan accordingly (via checked or unchecked).  Don't just follow the "checked for developing - unchecked for releasing" maxim unless you're completely aware of the implications!

    I started this post by mentioning IL and this is an interesting opportunity to glance at the IL generated by VB.Net and C#.  Using ILDasm (I discuss ILDasm a bit here or MSDN introduces it here), we can get under the hood of .Net.  Running ILDasm on our VB.Net example yields the following in the Button1_Click method (this snippet is about half way down in the method):
      IL_0018:  call       unsigned int8 [mscorlib]System.Byte::Parse(string)
      IL_001d:  add
      IL_001e:  conv.ovf.u1

    Note the "conv.ovf.u1" instruction; this is IL that forces an arithmetic overflow (ovf) check.  Use ILDasm to inspect the same C# method from our example (no checked statement or compiler option):
      IL_000b:  call       unsigned int8 [mscorlib]System.Byte::Parse(string)
      IL_0010:  stloc.0
      IL_0011:  ldloc.0
      IL_0012:  ldc.i4     0xc8
      IL_0017:  add
      IL_0018:  conv.u1

    Note the "conv.u1" instruction; this is IL that DOES NOT force and arithmetic overflow check.   

    [Update: Thanks to Greg Robinson for pointing out my ommision of the “Remove Integer Overflow Checks“ option on the VB.Net Project properties.  This will control the execution context of the VB.Net project like the C# “Check for Arithmetic Overflow/Underflow" option.] 

    We can see that the VB.Net and C# compilers produce different IL for roughly the same functionality.  I know of a few people who write some code in pure IL, and skip the higher level languages altogether.  This is much more like writing assembly language code and I'm not into that . . . I am, however, into using ILDasm to explore the nuances of IL as it relates to C# and VB.Net.  Try it out and you'll learn a lot about your .Net language of choice.

    Happy .Netting!

  • Don't Open Metabase.xml with WordPad

    Note to self:

    When you've enabled “Direct Metabase Edit“ in IIS, Notepad is good -- Wordpad is bad.

    Happy. Netting!

  • PimpedOutTextbox VB Style

    I've been asked by a few folks to provide a VB equivalent of the example C# web control I wrote about in this DotNetJunkies article.  It's taken me a few weeks to get around to it, but here's a quick translation (note, the formatting in .Text made this messy -- but I'm not going to bother reformating the post.  You can copy and paste and be in fine shape.  Enjoy!

    Imports System.ComponentModel

    Imports System.Web.UI

    imports System.Drawing

    <assembly: TagPrefix( "ControlLib" , "lib") >

     namespace ControlLib

    Public Class PimpedOutTextbox :

        Inherits System.Web.UI.WebControls.TextBox

        Private _colOff As Color

        Private _colOn as Color

    <Category( "Appearance" ), Description( "The background color when the control loses focus" )> _

                    public Property BackColorOff as Color

                                    get

                                                    return _colOff

                                    end get

                                    set( val as Color )

                                                    _colOff = val

                                    end set

                    end property

    <Category( "Appearance" ), Description( "The background color when the control has the focus" )> _

                    public Property BackColorOn as Color

                                    get

                                                    return _colOn

                                    end get

                                    set( val as Color )

                                                    _colOn = val

                                    end set

                    end property

                                   

                    protected overrides sub AddAttributesToRender( writer as HtmlTextWriter )

                                    MyBase.AddAttributesToRender( writer )

                                    'only add the client-side javascript for IE

                                    if( System.Web.HttpContext.Current.Request.Browser.Type.IndexOf( "IE" ) > -1 ) then

                                                    writer.AddAttribute( "onFocus", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( _colOn ) + "';" )

                                                    if( _colOff.Equals( Color.Empty ) ) then

                                                                    _colOff = Me.BackColor

                                                    end if

                                                    writer.AddAttribute( "onBlur", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( _colOff ) + "';" )

                                    end if

                     End Sub

    End Class

    End NameSpace

     

  • Some VB Static

    After a bit of time away, I'm teaching part-time again.  We were covering static members in VB and it ocurred to me (and the class) that static methods in VB exhibit different behaviour than in C#.  I do a lot of my programming with C#, and I was explaining how Shared (the VB equivalent to the C# static keyword) methods are available through instances of the class instead of just the type itself.  So, if I make a DeckOfCards object with a Shared (static) method named Sort(), the following is valid VB.Net:

    dim objInstance as DeckOfCards = new DeckOfCards()
    objInstance.Sort( args )

    In C#, the only way to call the static Sort method is through the type:

    DeckOfCards.Sort( args );

    Four things strike me:

    1. This is a fairly trivial thing . . .
    2. . . . Except that, to be technically correct, it means you have to caveat your explanation of Static methods based on each language.
    3. This is possibly (although I'm not sure) why VB.Net uses the keyword Shared in place of “static“.  Shared is not completely identical to the C# static.
    4. I like the c# way better; it's cleaner.  For example, the next question a student will ask is “can I reference the current instance though the Shared member?“  The rationale for static/shared methods comes into question . . .

    I can't think of a “good” reason for VB.Net exhibiting this behaviour, but I'm not on the VB.Net language team so who knows; it's not the first strange difference I've seen (see my post here for example) and it won't be my last.  Anyway, I thought I should document it here for posterity.

    Happy .Netting!

  • Mahalo in Advance for the Attribute Summary

    Just got back from a little holiday on a Pacific island where mahalo means Thank you . . . this was one of those vacations that helps me rationalize all the long hours during the rest of the year!

    Regarding the title of this post, a buddy asked me if I knew of a definitive resource on Attributes in the .Net Framework.  You know: a directory of each available attribute, the usage, and rationale.  I know the O'Reilly Programming VB.Net (by Grundgeiger) has an appendix listing Attributes and discusses the topic in some detail.

    Besides the O'Reilly book, I didn't know of anything off-hand and from googling etc, I couldn't find anything so I told him I wasn't aware of anything complete.  This seemed like something useful so I began listing the ones I knew of and used, thinking I could blog about a few attributes each day for a while . . . but then I decided to ask you all -- the blog public -- first . . .

    Do you know of an authoritative guide to the .Net Attributes available?

    Mahalo in advance!

     

More Posts