While creating a demo application for an upcoming blog post, I found myself with a method where I copy pasted the same code to work with three different types. I looked at the code and thought, "I should just create an interface for these small classes and rewrite this as one method that's called with three different types." But, one type was a reference to an asp.net 2.0 web service type, one was to a local type and one was a dictionary return from a call to a ServiceStack REST call. If there's a way to have those classes implement an interface after the fact, I don't know about it. But without even google/bing-ing a solution, I realized I could make this work by using the dynamic keyword. If all three types had the same method of interest and same signature, I could get away with passing them to the general use method even though they did not implement a common interface or inherit from the same base class.
Let's illustrate with some code:
I know, I know. It's bad code, but the save button isn't a lock button, so we can refactor. Furthermore, by using the dynamic keyword, we can refactor to this:
Much better right?
And now you can call each the method like this:
Keep in mind, none of these objects inherit from the same base class or implement the same interface. By convention I made sure that the AddThis method would be called the same way every time.
Nothing magical here, but it might get you out of a bind. I'm not sure that I'd want to put this in production code, at least not for every long, but it works.
Thursday, August 29, 2013
Wednesday, July 24, 2013
C# is Case Sensitive...Right?
Well...yes, of course. It's well known that C# is case sensitive(interesting discussion on this can be found here). If you declare a variable like this...
...it will be different than a variable declared this way...
One of the easiest ways to tell if your variables are spelled correctly is to try to compile your project. If your case is off, you'll get an exception at compile time and your code will not run at all. This is different from VB.Net, where variable names are not case sensitive in the VB.Net IDE.
is allowed because the VB.Net IDE ignores the case difference between "name" and "nAME". In VB.Net land, they are the same variable and you can't declare a variable with the same name in the same scope more than once. Note that the IDE allows you to get away with different cases in VB.Net. The compiler/CLR take care of case issues later(more here).
But while I was using Dapper, I noticed something odd. Sometimes the case between a class type<T> and the table column matched and sometimes they didn't but Dapper didn't seem to care at all. But if I called the .Query method without a <T> parameter, then case did matter.
If you call .Query in Dapper without a <T> parameter the method will return IEnumerable of type dynamic. I didn't know much about dynamic at the time but I assumed this would let you play fast and loose with property names. But that's not what happens. Dapper allows mis-matched case when referencing a Type property but if you don't specify a Type and you are dealing with IEnumerable of dynamic types, you have to match case or you get run time exceptions (not compile time exceptions). This is counter intuitive but that was obviously how it worked.
In this example I specify Type:
This works fine even though the column name that the PlayerID is referencing is "playerID". Column names are not case sensitive in MS SQL, but we're in that twilight zone where database types are mapped to CLR types. On the CLR side case sensitivity is going to make itself known. But it doesn't matter here. I can rename the column name to pLaYeRiD and it will still match to the property name PlayerID in my Player object.
But in this example, case does matter even though we are returning IEnumerable of dynamic.
This will throw a run-time exception Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with the text "Could not match up class property with object property."
Weird huh? Specify a Type and you can play fast and loose with the bindings. Don't specify a Type, go dynamic, and you have to match the property name case exactly to the the case of the column returned in the record set.
The thing to keep in mind with the dynamic "type" is that it's not really a type. There is still an underlying type that's the real type. When you use the dynamic type for a variable, you are saying to the compiler, "I got this. You don't need to check type whenever you see this variable during compile time." Does this sound a lot like the object type? It works exactly the same way in many circumstances. In fact, dynamic only exists at compile time. At run time it's converted into type object. (Read about it here on MSDN).
So what's Dapper doing behind the scenes here? Since it's an open source project we don't have to guess, we can look at the source code. This link will show the source code for how Dapper maps a Typed query. The part we really care about is in the GetMember method. If you step through that you'll see how the property names of the class are matched up with field/column names from the returned record set. The matching is done with the null coalescing operator:
StringComparison.Ordinal means to compare the strings by comparing a code for each char in the string. It's fast but culture dependent. Remember that Dapper was built for speed, so it reasons they chose speed over the ability to by culture independent. If it finds a match there, great. If it doesn't then it does the same comparison but with StringComparison.OrdinalIgnoreCase. OrdinalIgnoreCase converts each char in both strings to all upper case and then checks for a match. That's why you don't have to match case when comparing properties of a Type to columns in a returned record set. If it doesn't find a perfect match the first time, it coverts everything to upper case and checks again. I suspect matching case on both sides would result in slightly faster return times. Once a match is made an object of type SimpleObjectMap is returned.
So what about the dynamic side of things? It's a lot more straightforward...and convoluted. Lines 1635-1643 show where Dapper loops through the columns in the result set and makes a DapperTable filled with the names of the columns. If you step through the code you'll see that these are in turn converted to a collection of DapperRow and this is what is returned to the calling method undercover of dynamic. The DapperRow class builds "properties" that have the same name and type as the column returned from the database. Since these are properties, they have to be referred to with matching case. I could spend a few more posts just on the DapperRow class but that's the gist of how it works.
So case sensitivity holds up like it is supposed to in C#. If Dapper has a Type to work with in addition to a set of columns, it can make mappings for you even if you get the case wrong. If you are leaving it up to Dapper to return the result and and work without a column map you have to make sure the case is right for each property. Intellisense won't help you.
string name = "John";
...it will be different than a variable declared this way...
string nAme = "Smith";
One of the easiest ways to tell if your variables are spelled correctly is to try to compile your project. If your case is off, you'll get an exception at compile time and your code will not run at all. This is different from VB.Net, where variable names are not case sensitive in the VB.Net IDE.
Dim name as string ="John"and
nAME as string="Smith"
is allowed because the VB.Net IDE ignores the case difference between "name" and "nAME". In VB.Net land, they are the same variable and you can't declare a variable with the same name in the same scope more than once. Note that the IDE allows you to get away with different cases in VB.Net. The compiler/CLR take care of case issues later(more here).
But while I was using Dapper, I noticed something odd. Sometimes the case between a class type<T> and the table column matched and sometimes they didn't but Dapper didn't seem to care at all. But if I called the .Query method without a <T> parameter, then case did matter.
If you call .Query in Dapper without a <T> parameter the method will return IEnumerable of type dynamic. I didn't know much about dynamic at the time but I assumed this would let you play fast and loose with property names. But that's not what happens. Dapper allows mis-matched case when referencing a Type property but if you don't specify a Type and you are dealing with IEnumerable of dynamic types, you have to match case or you get run time exceptions (not compile time exceptions). This is counter intuitive but that was obviously how it worked.
In this example I specify Type:
Listplayers = cn.Query<Player> ("select * from player"); Console.Writeline("Player ID: {0}",players.FirstOrDefault().PlayerID);
This works fine even though the column name that the PlayerID is referencing is "playerID". Column names are not case sensitive in MS SQL, but we're in that twilight zone where database types are mapped to CLR types. On the CLR side case sensitivity is going to make itself known. But it doesn't matter here. I can rename the column name to pLaYeRiD and it will still match to the property name PlayerID in my Player object.
But in this example, case does matter even though we are returning IEnumerable of dynamic.
var players = cn.Query("select * from player"); Console.Writeline("Player ID: {0}",players.FirstOrDefault().PlayerID);
This will throw a run-time exception Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with the text "Could not match up class property with object property."
Weird huh? Specify a Type and you can play fast and loose with the bindings. Don't specify a Type, go dynamic, and you have to match the property name case exactly to the the case of the column returned in the record set.
The thing to keep in mind with the dynamic "type" is that it's not really a type. There is still an underlying type that's the real type. When you use the dynamic type for a variable, you are saying to the compiler, "I got this. You don't need to check type whenever you see this variable during compile time." Does this sound a lot like the object type? It works exactly the same way in many circumstances. In fact, dynamic only exists at compile time. At run time it's converted into type object. (Read about it here on MSDN).
So what's Dapper doing behind the scenes here? Since it's an open source project we don't have to guess, we can look at the source code. This link will show the source code for how Dapper maps a Typed query. The part we really care about is in the GetMember method. If you step through that you'll see how the property names of the class are matched up with field/column names from the returned record set. The matching is done with the null coalescing operator:
var property = _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.Ordinal)) ?? _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase));
StringComparison.Ordinal means to compare the strings by comparing a code for each char in the string. It's fast but culture dependent. Remember that Dapper was built for speed, so it reasons they chose speed over the ability to by culture independent. If it finds a match there, great. If it doesn't then it does the same comparison but with StringComparison.OrdinalIgnoreCase. OrdinalIgnoreCase converts each char in both strings to all upper case and then checks for a match. That's why you don't have to match case when comparing properties of a Type to columns in a returned record set. If it doesn't find a perfect match the first time, it coverts everything to upper case and checks again. I suspect matching case on both sides would result in slightly faster return times. Once a match is made an object of type SimpleObjectMap is returned.
So what about the dynamic side of things? It's a lot more straightforward...and convoluted. Lines 1635-1643 show where Dapper loops through the columns in the result set and makes a DapperTable filled with the names of the columns. If you step through the code you'll see that these are in turn converted to a collection of DapperRow and this is what is returned to the calling method undercover of dynamic. The DapperRow class builds "properties" that have the same name and type as the column returned from the database. Since these are properties, they have to be referred to with matching case. I could spend a few more posts just on the DapperRow class but that's the gist of how it works.
So case sensitivity holds up like it is supposed to in C#. If Dapper has a Type to work with in addition to a set of columns, it can make mappings for you even if you get the case wrong. If you are leaving it up to Dapper to return the result and and work without a column map you have to make sure the case is right for each property. Intellisense won't help you.
Saturday, July 13, 2013
Screencasting on a Budget
Scott Hanselman has a great post about making quality screencasts. If you want to get into the screencasting thing, go read it. If you are able to buy the recommended software and hardware that Scott recommends, great! No need for you to read further. But if you are on a budget or you want to make sure screen casting is really for you before you sink a lot of money into it, then read on...
That's really all you need. Total cost is $45 and some change. When you are recording be sure to turn off any fans, window A/C units, mobile phones, tablets and any program that might automatically pop up a notification or make a sound. If you have any three year olds in the house, you might want to wait until they are asleep.
Once you've exported your screen cast to a video file, you can upload it to You Tube for free, or you can use Vimeo. I suggest you check out Vimeo, they have a basic plan that's free. I decided to use Vimeo Plus which costs me $9.99/month. So far I've been very pleased with the service. If you want to keep costs low at the start, stay with You Tube but you will probably see the need for more than the free service that You Tube offers if you continue screen casting. There are a number of comparison articles on Vimeo vs You Tube to help you decide.
- Don't use your computer/laptop microphone. You're going to need a new microphone. I didn't have $100+ (or $300+) to spend on a mic, so I bought the Samson Go Mic (on Amazon) for $39.99. It's a USB mic (which is important) and it's very highly reviewed. It has worked great for me both for screen casts and for interviews for my linguistics class. This is the most expensive thing I've purchased for screen casting.
- Download Audacity. You need a way to modify the sound from your screen casts. Audacity is free. Learn how to insert silence, add a music track, fade in, fade and most importantly, Noise Removal.
- Download Screencast O Matic. You can use the free version but go ahead and spend the money on the pro version, it's $15 a year. You are going to need the tools in the pro version to cut out your mistakes, add transitions (like dissolves) and most importantly, export and and import your audio track (which you cleaned up using Audacity).
That's really all you need. Total cost is $45 and some change. When you are recording be sure to turn off any fans, window A/C units, mobile phones, tablets and any program that might automatically pop up a notification or make a sound. If you have any three year olds in the house, you might want to wait until they are asleep.
Once you've exported your screen cast to a video file, you can upload it to You Tube for free, or you can use Vimeo. I suggest you check out Vimeo, they have a basic plan that's free. I decided to use Vimeo Plus which costs me $9.99/month. So far I've been very pleased with the service. If you want to keep costs low at the start, stay with You Tube but you will probably see the need for more than the free service that You Tube offers if you continue screen casting. There are a number of comparison articles on Vimeo vs You Tube to help you decide.
Friday, July 12, 2013
Getting Started With Dapper Part 3
In part three I cover how to use alternate constructors for types used with Dapper. In parts 1 & 2 I used the default parameterless constructor but that doesn't work in every situation.
Dapper can also make use of a constructor that matches the type and field names returned in a recordset in addition to completely custom constructors that don't mach up to returned recordsets.
Lastly, I cover how to use a custom constructor and initialize a property during the Dapper mapping using Ling and a simple lambda expression.
Intro To Dapper - Part 3 from Jon Wear on Vimeo.
Source code: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt3.zip
Dapper can also make use of a constructor that matches the type and field names returned in a recordset in addition to completely custom constructors that don't mach up to returned recordsets.
Lastly, I cover how to use a custom constructor and initialize a property during the Dapper mapping using Ling and a simple lambda expression.
Intro To Dapper - Part 3 from Jon Wear on Vimeo.
Source code: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt3.zip
Friday, June 28, 2013
Getting Started With Dapper Part 2
This video is part 2 of a very basic introduction to the micro ORM Dapper for use with the .Net platform. I go over IEnumerable and how it relates to Dapper, as well as demonstrating several different classes that implement IEnumerable (Lists, Arrays, Dictionaries).
I also go over what happens with .First and .FirstOrDefault when used with Dapper/IEnumerable and how the behavior can be different for value types vs. reference types.
The source code for this project can be found here:
You can find more info about Dapper here: code.google.com/p/dapper-dot-net/.
Tuesday, June 25, 2013
An apology to Jon Skeet
Mr. Skeet doesn't know me and no one that knows me has ever heard me say anything negative about him, so it may seem odd that I'm writing this apology.
But sometimes, when no one is around, and I'm watching a video from tekpub (like one of these), I find myself drumming my fingers and eventually I yell something like this:
"GET TO THE POINT! I don't care about every last little nuance of the CLR! Who cares if Ildasm looks different for this or that, just tell me about Lambdas! Great Caesar's Ghost! Just stop it already, quit bringing up Noda-Time and get to point!".
Well, I'm trying to make some screen casts of my own and in addition to trying to get the sound to...sound right, I'm realizing that many times you have to go deep into the details or you aren't explaining things properly.
Take my first stab, Getting Started With Dapper. Dapper has been out for a while (most howto posts regarding Dapper are from 2011) so I thought it would be fairly easy to do a screen cast on it. I've used it a lot. I know my way around it. Piece of cake, right?
Everything was going fine until I realized that I didn't really explain why I put a ToList() on the end of my Dapper.Query<T> calls. The reason, of course, is that I like working with generic lists and .Query<T> returns IEnumerable<T>. So I throw on a .ToList() to get things like I want them. But that brings up the question, why does Dapper do that? If I don't explain why IEnumerable is used instead of other collection types, then I'm really doing a screen cast on how I use Dapper rather than what Dapper does.
So I started writing text for an aside on IEnumerable. I quickly realized this needed to be it's own separate screen cast because when you hit the period after typing .Query<T>("") there are a kah-jillion other Linq extension methods that pop up:
I didn't go crazy and spend time on each one, but there are several that need to be discussed. And they behave differently with value types vs. references types and reference types behave differently than nullable reference types and...sheesh. I just wanted to make a screen cast about Dapper and expand the brand a little bit and now I'm looking through the C# specifications!
I'm taking my time and hopefully making good choices about what needs to be discussed and what can be left out. But, there's more to it than I originally thought.
And while I can't claim to have walked a mile in Jon Skeet's shoes (his SO score is 576,875 while mine is...6), I can say that I've walked, maybe an metaphorical inch in his shoes. After travelling even such a short distance as this, I feel compelled to say to Mr. Skeet, "I'm sorry I yelled at your tekpub video late at night when no one could hear me. I just didn't know."
Just before I scheduled this post, I went to Mr. Skeet's twitter page and saw this exchange:
Pretty good advice.
But sometimes, when no one is around, and I'm watching a video from tekpub (like one of these), I find myself drumming my fingers and eventually I yell something like this:
"GET TO THE POINT! I don't care about every last little nuance of the CLR! Who cares if Ildasm looks different for this or that, just tell me about Lambdas! Great Caesar's Ghost! Just stop it already, quit bringing up Noda-Time and get to point!".
Well, I'm trying to make some screen casts of my own and in addition to trying to get the sound to...sound right, I'm realizing that many times you have to go deep into the details or you aren't explaining things properly.
Take my first stab, Getting Started With Dapper. Dapper has been out for a while (most howto posts regarding Dapper are from 2011) so I thought it would be fairly easy to do a screen cast on it. I've used it a lot. I know my way around it. Piece of cake, right?
Everything was going fine until I realized that I didn't really explain why I put a ToList() on the end of my Dapper.Query<T> calls. The reason, of course, is that I like working with generic lists and .Query<T> returns IEnumerable<T>. So I throw on a .ToList() to get things like I want them. But that brings up the question, why does Dapper do that? If I don't explain why IEnumerable is used instead of other collection types, then I'm really doing a screen cast on how I use Dapper rather than what Dapper does.
So I started writing text for an aside on IEnumerable. I quickly realized this needed to be it's own separate screen cast because when you hit the period after typing .Query<T>("") there are a kah-jillion other Linq extension methods that pop up:
I didn't go crazy and spend time on each one, but there are several that need to be discussed. And they behave differently with value types vs. references types and reference types behave differently than nullable reference types and...sheesh. I just wanted to make a screen cast about Dapper and expand the brand a little bit and now I'm looking through the C# specifications!
I'm taking my time and hopefully making good choices about what needs to be discussed and what can be left out. But, there's more to it than I originally thought.
And while I can't claim to have walked a mile in Jon Skeet's shoes (his SO score is 576,875 while mine is...6), I can say that I've walked, maybe an metaphorical inch in his shoes. After travelling even such a short distance as this, I feel compelled to say to Mr. Skeet, "I'm sorry I yelled at your tekpub video late at night when no one could hear me. I just didn't know."
Just before I scheduled this post, I went to Mr. Skeet's twitter page and saw this exchange:
Pretty good advice.
Friday, June 21, 2013
My First Screen Cast - Getting Started with Dapper Pt1.
So I decided to try my hand at screen casting. This is my first effort and I found, as many others have before me, it's not easy getting a screen cast to look anything close to decent. But practice makes...something less bad than before. Anyway, enough with the self depreciation.
Intro To Dapper - Part 1 from Jon Wear on Vimeo.
Source code can be found here: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt1.zip
This screen cast is a very basic introduction to the Mirco ORM Dapper. This and the next several screen casts will be targeted towards what I refer to as "default developers". Default developers are developers (like myself a few years ago) who primarily take what Microsoft gives them. If it's not "in the box" or on MSDN, then it's not on the radar. It is not my intention to demean the default developer. Like I said, I used to be one. My intention is to make the material covered as approachable as possible crack open the door to all the great non-Microsoft things that are being done with .Net.
So check out my Dapper video. If you have any suggestions for improvements or think I got something flat out wrong, please let me know in the comments or send an email.
Intro To Dapper - Part 1 from Jon Wear on Vimeo.
Source code can be found here: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt1.zip
Subscribe to:
Posts (Atom)