views:

628

answers:

3

I guess this could also be asked as to how long the created type name is attached to an anonymous type. Here's the issue:

A blog had something like this:

var anonymousMagic = new {test.UserName};

lblShowText.Text = lblShowText
                     .Text
                     .Format("{UserName}", test);

As sort of a wish list and a couple ways to go at it. Being bored and adventurous I took to creating an string extension method that could handle this:

var anonymousMagic = new {test.UserName, test.UserID};

lblShowText.Text = "{UserName} is user number {UserID}"
                     .FormatAdvanced(anonymousMagic);

With the idea that I would get the property info from the anonymous type and match that to the bracketted strings. Now with property info comes reflection, so I would want to save the property info the first time the type came through so that I wouldn't have to get it again. So I did something like this:

    public static String FormatAdvanced(this String stringToFormat, Object source)
    {

        Dictionary<String, PropertyInfo> info;
        Type test; 
        String typeName;
        //
        currentType = source.GetType();
        typeName = currentType.Name;
        //
        //info list is a static list for the class holding this method
        if (infoList == null)
        {
            infoList = new Dictionary<String, Dictionary<String, PropertyInfo>>();
        }
        //
        if (infoList.ContainsKey(typeName))
        {
            info = infoList[typeName];
        }
        else
        {
            info = test.GetProperties()
                       .ToDictionary(item => item.Name);
            infoList.Add(typeName, info);
        }  
        //
        foreach (var propertyInfoPair in info)
        {
            String currentKey;
            String replacement;

            replacement = propertyInfoPair.Value.GetValue(source, null).ToString();
            currentKey = propertyInfoPair.Key;

            if (stringToFormat.Contains("{" + currentKey + "}"))
            {
                stringToFormat = stringToFormat
                                 .Replace("{" + currentKey + "}", replacement);
            }
        }  
        //
        return stringToFormat;
    }

Now in testing, it seems to keep the name it created for the anonymous type so that the second time through it doesn't get the property info off the type but off the dictionary.

If multiple people are hitting this method at the same time, is it pretty much going to work in a Session like fassion; IE the names of the types will be specific to each instance of the program? Or would it be even worse than that? At what point does that name get chucked and overwritten?

+3  A: 

It never does. The type is generated at compile-time and you can consider it constant and unique throughout the life of the app-domain.

I question the value of this function though. The obvious first reason is because you don't have much of the functionality of the Format method on the String class (no escape for brackets, no formatting of values in the brackets, etc, etc).

The second is that it basically links the format string to the type being passed in, so they are not swapped out easily. If I had two classes which had the same conceptual value, but different properties naming it, I have to change my format string to display it with your method to compensate for the fact that the property name is embedded in the format string.

casperOne
The main idea is that I could get around having to create a large array of stuff and have the 1,2,3,4 accompanying it. Not saying this is a great idea in any way, just thought it might be an interesting exercise.
Programmin Tool
+2  A: 

Anonymous types are generated at compile time, and so the reflection names should be static as long as you don't re-compile the assembly.

There is a detailed post here that describes the names, but I believe what you are doing is safe.

Steve Mitcham
+1  A: 

I have two things to say, but this isn't really an answer.

First of all, the Dictionary doesn't have to have a string key; the key could be the actual type. i.e. it could be a Dictionary<Type, Dictionary<String, PropertyInfo>>. That would be faster because you don't have to get the type name, and less error prone - what if I send that method two non-anonymous types with the same name but different namespaces?

Second, you should read Phil Haack's recent blog post about this subject. It contains a full implementation of such a method.

configurator
I think that's where I got the original idea from but wanted to try it on my own to see if I could. And honestly, so far this passes the bracket test and is very fast after the first time around. But yeah, probably wouldn't hurt me to read the whole post.
Programmin Tool