Thursday, April 12, 2007 6:11 PM bart

C# Quiz - Fun with System.Xml

A simple quiz today; it's rather a System.Xml debugging job. With this I've said too much already. Here it is:

Copy Code
1 using System; 2 using System.Xml; 3 4 class Program 5 { 6 static void Main() 7 { 8 new Bar<int>().CreateBar<double>("Bart").CreateBar<long>("DeSmet"); 9 } 10 } 11 12 class Bar<T> 13 { 14 static XmlDocument doc = new XmlDocument(); 15 16 private XmlElement root; 17 18 public Bar() 19 { 20 root = doc.CreateElement("Root"); 21 } 22 23 private Bar(XmlElement root) { this.root = root; } 24 25 public Bar<S> CreateBar<S>(string foo) 26 { 27 XmlElement f = doc.CreateElement(foo); 28 root.AppendChild(f); 29 return new Bar<S>(root); 30 } 31 }

Questions:

  1. Which exception will this code produce?
  2. Can you explain why (tip: line 14 was declared as static for some reason...)?
  3. Will you see the same behavior regardless of the code in Main? Why (not)?
  4. What [is a | are] possible solution[  | s]?

Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# re: C# Quiz - Fun with System.Xml

Thursday, April 12, 2007 7:49 PM by Matthew W. Jackson

1) NullReferenceException

2) Bar<int>, Bar<double> and Bar<long> are distinct classes with their own static members, so you are actually referencing Bar<int>.doc, Bar<double>.doc and Bar<long>.doc, which fit in three separate memory locations.  Think of it as a lazy-initializing Dictionary<Type, XmlDocument>, which can be quite handy, but not in this case.

3) This won't happen if you change Main to:

new Bar<int>().CreateBar<int>("Bart").CreateBar<int>("DeSmet");

4) Depending on what you're actually trying to accomplish: Put the static field in a non-generic class, or make it non-static and pass it to the private constructor directly.

# re: C# Quiz - Fun with System.Xml

Thursday, April 12, 2007 11:34 PM by Michael Lapinsky

1. System.ArgumentException on line 28

2. Because the XmlDocument that created the element in Bar<int>.CreateBar() is different than the one used to create the element in Bar<double>.CreateBar().  That is, they're two different classes (after instantiating Bar for int and double), thus two different static members.

3. Nope, if all of the Bar instantiations (except for the last one) were of the same type (all int, all double, all long, ...) then this exception wouldn't occur.

4. (3) is a possible solution, or get rid of the generics altogether if you don't actually need them, or make Bar an inner class and make "doc" a (static or instance) member of the outer class.

# re: C# Quiz - Fun with System.Xml

Sunday, April 15, 2007 7:28 AM by Eamon Nerbonne

1. ArgumentException in non-static method CreateBar<long>() of class Bar<double>

2. This instance of Bar<double> will have a root variable provided by the CreateBar<double> call of Bar<int>, but will use the document it (Bar<double>) statically creates.  Thus the root element is "owned" by document Bar<int>.doc wheras the element it tries to append has been created by Bar<double>.doc - which is impossible.

3. The code in main will cause this exception exactly when a Bar<T> element is constructed, and a CreateBar<S> method called on it, and a CreateBar<R> called on its return value where S != T.

3. Well you can hack around it by only using one template type (defeating the (non-)purpose of genericity), or you can remove the generics entirely, or you can import the "root" node provided during construction into the appropriate document.  You could also extract the document variable from the provided root element and not make the "doc" field static (it's very odd to have a static document like this anyways - but then this is quiz-code ;-).  Finally, the root-cause is the confusing DOM specification which uses a document-centric model that requires you to constantly be aware of "which" document you're working with.  A very appropriate fix would thus simply be to ditch DOM and use XLinq ;-).

# Answers to C# Quiz - Fun with System.Xml

Wednesday, April 18, 2007 1:57 AM by B# .NET Blog

Answers to the C# Quiz - Fun with System.Xml . Here's a quick refresh of the problem: Copy Code 1 using