More IL features missing from C#
April 20, 2009 at 09:30 PM | categories: Uncategorized | View Comments Wesner Moise wrote about IL features missing in C#: extended precision for floating-point calculations, and tail call optimizations. His post reminded me of a few more IL features that could be useful in C# but that aren't exposed or aren't documented.ldtoken
: This is the opcode behind typeof
. ldtoken
also operates on fields and methods, opening up the possibility of hypothetical fieldof
and methodof
keywords: these might return FieldInfo
and MethodInfo
objects at runtime respectively, allowing you to write reflection code that's checked at compile time.
There is in fact a trick you can use to get hold of a MethodInfo
object without having to call Type.GetMethod
or the like:
MethodInfo methodInfo = new Action<string>(Console.WriteLine).Method;
However, because this trick instantiates a new delegate to use its Method
property, it's only useful when:
- You're dealing with static methods
- You have an instance of the right type
Note that this trick doesn't work on property accessors, since there's no delegate syntax for these like there is for methods.
Typed references: You may have noticed the System.TypedReference
class documented in MSDN, and wondered what it was useful for. C# supports typed references -- effectively safe, verifiable pointers -- via three undocumented keywords.
int i = 42; TypedReference reference = __makeref(i); Debug.Assert(__reftype(reference) == typeof(int)); Debug.Assert(__refvalue(reference, int) == 42);
I haven't seen any official statement from Microsoft saying that this technique is going to stop working any time soon, but they don't seem to be in a hurry to fix bugs relating to these keywords.
Making sense of XSD type names, in C#
April 17, 2009 at 11:00 PM | categories: Uncategorized | View CommentsIn response to a conversation with @phil_nash earlier this week:
I have some data from an XML document, along with a string indicating the type of that data, as one of the XSD type names. The .NET XML serializer knows all about these XSD types, since it'll emit xsi:type attributes on elements that correspond to .NET properties of type object.
However, there doesn't seem to be an easy way of parsing these XSD type names from your own code. A little digging led me to the XmlSerializationReader.ReadTypedPrimitive method, which is (naturally) declared as private.
At this point I have three options:
- Call ReadTypedPrimitive directly, using Reflection. Evil, since I'd rather not write code that accesses framework methods declared as private.
- Write my own equivalent of the ReadTypedPrimitive method. This appears to involve a giant switch statement.
- Come up with some way of persuading the framework to call ReadTypedPrimitive on my behalf.
The XmlSerializationReader class is in fact used as a base class for the code generated for you when you call the XmlSerializer constructor. I realised that, in order to arrange for the framework to make this method call, I just need a small serializable class that results in the right auto-generated code.
In summary, I went with option 3: construct an XML document in memory, containing the string I originally wanted converted, and the XSD type name supplied to me. Running that through the XmlSerializer causes ReadTypedPrimitive -- with its large switch statement -- to get called, and I end up with a .NET object whose type corresponds to the XSD type of my choice.
using System; using System.Diagnostics; using System.Xml; using System.Xml.Serialization; public class XmlValueWrapper { private object value; public object Value { get { return value; } set { this.value = value; } } } public static class XsdConvert { private static XmlSerializer serializer = new XmlSerializer(typeof(XmlValueWrapper)); public static object ConvertFrom(string value, string xsdType) { XmlDocument doc = new XmlDocument(); XmlElement rootElement = (XmlElement) doc.AppendChild(doc.CreateElement("XmlValueWrapper")); rootElement.SetAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema"); XmlElement valueElement = (XmlElement) rootElement.AppendChild(doc.CreateElement("Value")); valueElement.SetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance", xsdType); valueElement.AppendChild(doc.CreateTextNode(value)); using (XmlNodeReader reader = new XmlNodeReader(doc)) { XmlValueWrapper wrapper = (XmlValueWrapper) serializer.Deserialize(reader); return wrapper.Value; } } } public static class Program { public static void Main() { Debug.Assert(Equals(42, XsdConvert.ConvertFrom("42", "xs:int"))); Debug.Assert(Equals(42.0, XsdConvert.ConvertFrom("42", "xs:double"))); Debug.Assert(Equals(42m, XsdConvert.ConvertFrom("42", "xs:decimal"))); Debug.Assert(Equals("42", XsdConvert.ConvertFrom("42", "xs:string"))); Debug.Assert(Equals(true, XsdConvert.ConvertFrom("true", "xs:boolean"))); Debug.Assert(Equals(new DateTime(2009, 4, 17), XsdConvert.ConvertFrom("2009-04-17", "xs:date"))); } }
About this blog
April 16, 2009 at 09:00 AM | categories: Uncategorized | View CommentsI'm not sure how this will turn out, but what I'm hoping to do here is to write about whatever side project I happen to be doing at the time. This blog is likely to stay technical: I'm planning to keep my photography separate at http://www.partario.com/photos/. I reckon this blog -- with the writing -- is likely to have a different kind of audience from the photoblog.
First post
April 15, 2009 at 08:33 PM | categories: Uncategorized | View CommentsI wanted to avoid both the "hello world" first post, and generally blogging about blogging. However, I was moderately impressed about how easy this was to set up, seeing as I'm hosting this site on my own PC:
- Virtual server (Microsoft Virtual Server), since I didn't want to have connections coming directly onto the PC that has all my important files
- A pretty minimal server installation of Ubuntu 8.10
- A couple of Apache virtual hosts
- Movable Type
Ubuntu was surprisingly easy to set up: my last successful Linux experience was probably Slackware in 1999 or so. I haven't needed to try the desktop side of things yet, but Ubuntu has a level of polish similar to OS X.
One snag in the installation was that the Ubuntu console appeared corrupted under MSVS's web-based remote control, so that I could only see the first few lines. I didn't feel like digging too far into the frame buffer configuration, so I set up ssh and did the rest of the installation remotely from OS X's Terminal.
Active Directory integration was equally easy: installing Likewise Open allowed me to start logging onto my new virtual Linux server using my Windows user name and password. (I have the same setup on the Mac: the same user name and password logs into email, file shares, and OS X itself.)
The Apache and Movable Type installation came courtesy of a Google search on "ubuntu movable type" and went through without a hitch. In the past I've have run things like this on Windows through Cygwin, and have spent most of the time hacking mount points and \ vs. /. Deploying on Linux is clearly what I was supposed to be doing.
« Previous Page
Social networking sites via Excel?
April 17, 2009 at 04:45 PM | categories: Uncategorized | View Comments Spreadtweet makes Twitter look like Excel:We need more of this kind of thing – Faceworkbook, anyone? Maybe I’ve been programming Excel too long, if I’m getting excited about this.