C#: Multiple Dynamic Properties on a Class Either Defined or with Generics

Posted by OmegaMan at July 27, 2010

Category: C#, How To

Tags: ,

Using the class indexer of C# (abc[ xxx ] = yyy) we can create a class which has multiple dynamic properties associated by a string or whatever we want as the key for access. In the example below we use a string as our access key and holds a string as a value. The storage is accomplished by using a dictionary. See the Usage method below on how to access it.

public class MultipleDynamicProperties
{

    private Dictionary<string, string> _dynamicProperties = new Dictionary<string, string>();    
    
    // Index the data here  
    public string this[string key]
    {
        get
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
                _dynamicProperties.Add( key, string.Empty );

            return _dynamicProperties[key];
        }
        set
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
                _dynamicProperties.Add( key, value );
            else
            {
                _dynamicProperties[key] = value;
            }
        }
    }

    /// <summary>
    /// Example don't use in your code.
    /// </summary>
    public static void Usage()
    {
        MultipleDynamicProperties mdc = new MultipleDynamicProperties();

        mdc["Jabber"] = "1st Attempt";
        mdc["Jabber"] = "Wocky";
        mdc["Omega"] = "Man";

        Console.WriteLine("Jabber: " + mdc["Jabber"]); // Printers Jabber: wocky

    }

}

Using other index types say integer or enum, we can accomplish the same goal by changing or adding to our index’able properties of the class. We could have multiple accessors as long as the key is not the same. Below is an example using an enum as the key and a List<string> as the value returned:

public class MultipleDynamicPropertiesWithEnum
{
    public enum Operation
    {
        TargetA,
        TargetB,
    }

    private Dictionary<Operation, List<string>> _dynamicProperties = new Dictionary<Operation, List<string>>();


         // Index the data here  
    public List<string> this[Operation key]
    {
        get
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
                _dynamicProperties.Add( key, new List<string>() );

            return _dynamicProperties[key];
        }
        set
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
                _dynamicProperties.Add( key, value );
            else
            {
                _dynamicProperties[key] = value;
            }
        }
    }

    public static void Usage()
    {
        MultipleDynamicPropertiesWithEnum show = new MultipleDynamicPropertiesWithEnum();

        show[Operation.TargetA] = new List<string>() { "Jabber" };
        show[Operation.TargetB] = new List<string>() { "Wocky" };

        // Prints Jabberwocky 
        Console.WriteLine( show[Operation.TargetA][0] + show[Operation.TargetB][0] );
    }
}

 

Generic Option

But why limit ourselves, why not make the accessor generic, so the user/consumer can dictate what the keys and what data is returned. Here is the generic version where we mimic the hard coded version of string and string.

/// <summary>
/// This class has a generic indexor defined by the generic parameters specified
/// by the consumer.
/// </summary>
/// <typeparam name="KY">Key type to use to acces the value type to store.</typeparam>
/// <typeparam name="T">The value type to store.</typeparam>
/// <remarks>See Usage on how to use.</remarks>
public class MultipleDynamicPropertiesAsGeneric<KY, T>
{

    private Dictionary<KY, T> _dynamicProperties = new Dictionary<KY, T>();

    // Index the data here  
    public T this[KY key]
    {
        get
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
            {
                _dynamicProperties.Add( key, Activator.CreateInstance<T>() );
            }

            return _dynamicProperties[key];
        }
        set
        {
            if ( _dynamicProperties.ContainsKey( key ) == false )
                _dynamicProperties.Add( key, value );
            else
            {
                _dynamicProperties[key] = value;
            }
        }
    }

    public static void Usage()
    {
        MultipleDynamicPropertiesAsGeneric<string, string> show = new MultipleDynamicPropertiesAsGeneric<string, string>();

        show["Jabber"] = "Wocky";

        // Prints wocky 
        Console.WriteLine( show["Jabber"] );

    }

}
Share

8 Comments

  1. Omer Mor says

    What is the difference between MultipleDynamicPropertiesAsGeneric and a standard generic Dictionary? The dictionary also exposes its values through an indexer.

    Reply
    • OmegaMan says

      There is no difference with the class basically being a wrapper for dictionary. This article was meant as a learning example for a user’s post on MSDN: Unknown number of properties using generics

      Reply
  2. Brian says

    Is there a way you can bind a list of MultipleDynamicProperties objects to a GridView?

    Reply
    • OmegaMan says

      You would have to specify the bindings depending on what grid we are talking about asp.net, silverlight/wpf or winforms. Post your question to the MSDN or asp.net forums for a better answer depending on which you are using.

      Reply
  3. Manu Parashar says

    Thats a good code snippet for unknown number of properties and unknown type of properties … I am using it something like this –
    MultipleDynamicPropertiesAsGeneric show = new MultipleDynamicPropertiesAsGeneric();
    Cheers

    Reply
  4. Manu Parashar says

    Thats a good code snippet for unknown number of properties and unknown type of properties … I am using it something like this –
    MultipleDynamicPropertiesAsGeneric show = new MultipleDynamicPropertiesAsGeneric();

    Reply
  5. Manu Parashar says

    Its somehow deleting object, object ..

    Reply
  6. Philip says

    Is there a way to loop through all the properties/members of a class passed in – as in my question on StackOverflow?

    I have several web-services that need the SoapBody populated from a string array which is defined by an enumerated constant (the enum matches the members of the web-service class)

    Reply

Leave a comment

(required)
(required) (will not be published)

This site uses Akismet to reduce spam. Learn how your comment data is processed.