5

I want to retrieve values from a tree stored in another system. For example:

GetValue("Vehicle.Car.Ford.Focus.Engine.Oil.Color")

To avoid typing errors and invalid keys, I want to check the name at compile time by creating an object or class with the tree structure in it:

GetValue(Vehicle.Car.Ford.Focus.Engine.Oil.Color)

Is there an easy way to do this in C# without creating classes for each tree node? Can I use anonymous classes or subclasses? Should I create the code automatically?

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
  • You could (should) create the code automatically – sehe Jun 09 '11 at 07:59
  • Do you mean that this is like a class hierarchy? – Tony The Lion Jun 09 '11 at 08:00
  • Yes, a class hierarchy. Oil.Color would probably be a string containing the key. – Sjoerd Jun 09 '11 at 08:06
  • 1
    You could do this with a pile of properties and type casting, with a class tree or other similar methods, but it seems a bit of an odd thing to do -- if the structure you are using is hard-coded, then you only have one chance to mis-type. If it's not hard-coded, then you're going to run into problems trying to reproduce the tree structure twice -- much more chance of making mistakes. – Iain Ballard Jun 09 '11 at 08:14

4 Answers4

4

If you want compile-time checking, you need to define your structure using compile-time constructs in some way. You could use T4 text template to automatically generate code from the tree structure.

Possible ways I can think of:

Nested static classes

public static class Vehicle
{
    public static class Car
    {
        public static class Ford
        {
            public static class Focus
            {
                public static class Engine
                {
                    public static class Oil
                    {
                        public static readonly string Color =
                            "Vehicle.Car.Ford.Focus.Engine.Oil.Color";
                    }
                }
            }
        }
    }
}

Namespaces and static classes

namespace Vehicle.Car.Ford.Focus.Engine
{
    public static class Oil
    {
         public static readonly string Color =
             "Vehicle.Car.Ford.Focus.Engine.Oil.Color";
    }
}

(Note that you can't have both a class Ford in namespace Vehicle.Car and classes in a namespace Vehicle.Car.Ford.)

dtb
  • 213,145
  • 36
  • 401
  • 431
1
  • You can't do this without creating classes for each tree node
  • Anonymous types and/or subclasses won't help here (at least I can't see how)
  • You can generated the classes automatically, you will need to write a code generator for it, or use an existing one such as t4 or CodeSmith. You will still need to write some code even with an existing code generator to tell it how to generate your classes.
Andrew Savinykh
  • 25,351
  • 17
  • 103
  • 158
1

Try some thing like this:

var Vehicle = new { Car = new { Ford = new { Focus = new { Engine = new { Oil = new {Color = "Red"}}}}}};

Now you can get each value with intellisence.

Although I prefer @dtb approach. Still I think my approach is quite light weight.

Hasan Fahim
  • 3,875
  • 1
  • 30
  • 51
0

You can probably find a way to do it with C# Extension methods: http://msdn.microsoft.com/en-us/library/bb383977.aspx

But there's probably no escape from some automatic code generation

Variant
  • 17,279
  • 4
  • 40
  • 65