Dapper: What's the difference between these two pieces of code?

Question

I've registered a custom type handler for Dapper to Json serialize a string. This works as expected. However, whilst coding, I discovered two pieces of code after refactoring, the latter one which didn't trigger the datatype handler, but should in my opinion, so what's the difference?

First the code that works as expected - the custom type handler is called by dapper, and the data is serialized when inserted into the table:

Is it a dapper bug or a c# oddity? I assume it's something to do with the auto typing in the ternary conditional which is the failing point, but t is set to the data type that is serialized by Dapper (or rather the custom type handler). What's the difference?

At compile-time, a best common type for JsonString and object must be found. That common type is object. So object becomes the compile-time type of v here, i.e. var means object here.

Then the anonymous type:

new { keyName, v }

is a type "Anonumous2" whose "2nd" property reads:

public object v { get { ... } }

So to sum up: In the first case you pass in an object which has a property v declared as a JsonString which when retrieved returns a JsonSting that happens to have run-time JsonString. In the second code sample you pass in an object which has a property v declared as object which when retrieved returns an object that happens to have run-time type JsonString.

I do not know much on how Dapper works! But presumably when it sees (by reflection?) that the property type is object, it simply calls .ToString() on it. If that object happens to be of run-time type string, that should be OK, since string.ToString() is overridden. But JsonString.ToString() is not like that.

When Dapper sees the property is declared as JsonString, Dapper does something smarter than calling .ToString().

Popular Answer

Assuming there is no implicit conversion available between JsonString and String, the code in the second example won't work. If there is an implicit conversion available, you need to provide more information about the exception that is occurring.

WIth no conversion available between JsonString, a variable declared with type var has a type that is inferred by the compiler ((https://msdn.microsoft.com/en-us/library/bb384061.aspx). In this case, variable v is either of type JsonString or String depending upon which part of the assignment occurs. If the compiler assumes it is of type JsonString, any assignment with a String will fail.

In your second code example, the first line of code is wrong since the assignment results in two different data types getting assign to variable v.