Click here to Skip to main content
13,353,706 members (59,045 online)
Click here to Skip to main content
Add your own
alternative version


26 bookmarked
Posted 5 Sep 2010

Objects With Customizable Properties

, 25 Apr 2011
Rate this:
Please Sign up or sign in to vote.
A class with customizable properties without using Reflection.


Why did I write this? I was in need of a more or less dynamic class where I could customize properties by configuration.


My first approach was the classical "use-a-dictionary", but this left me with the decision to using a string as the key (I'm staying with that) and... what type as value?

Using object as value could bypass strong typing and I would not like to lose it. Also, I needed a possibility to iterate through properties without using Reflection in the client, even to define some of the properties to be read-only.

Last but not least, it should be possible to gain the value of a fixed property defined by an interface (read and write).

All in all, pretty much like M. Fowler mentioned in his article "Dealing with Properties".

The Code Behind

The code is divided into two assemblies:

  • Interfaces to an object with customizable properties.
  • An implementation of the mentioned interface.

The interface is nothing fancy. Just a small interface to an object with properties.

public interface IObjectWithProperties {

    event EventHandler<SMoni.ObjectWithProperties.
              Interfaces.PropertyChangedEventArgs> PropertyChanged;

    object this[string Key_] { get; set; }

    T      getValueOf<T>(string Key_);
    object getValueOf(string Key_);

    void setValueOf(string Key_, object Value_);
    void setValueOf(KeyValuePair<string, object> KeyValuePair_);

    DictionaryEntry[] Properties { get; }

    bool canWrite(string Key_);

    bool hasProperty(string Key_);
    bool areTypesEqual(string Key_, object Value_);    


The method hasProperty could be used to make sure the property exists, and canWrite to check if the property is writable. areTypesEqual should be called to make sure that the type of the given key and the value are the same.

For getting values, there are three possible ways (OK... there's a fourth, but I will explain this one later) to obtain a value by a given key:

  • index
  • getValueOf method which returns an object
  • getValueOf method with a generic, which returns a value with the generic-type, if the type matches

The methods could also return the value of a fixed property.

For setting a value, there are three possible ways (this time, really only three):

  • index
  • setValueOf method with a KeyValuePair
  • setValueOf method with a straight key as String and a value as Object

With all set-methods, it is also possible to set a fixed property.

Further, the properties in dictionaries fire an event if they have been changed. Attention: "normal" properties are not covered.

Last but not least, it is possible to query all properties using Properties[].

To avoid showing/using "normal" properties in Properties[] and by get-methods, the attribute [DoNotShowInProperties] could be used. Either in an interface or in the class itself.

public [...] PropertyWhichIsNotShownInProperties {
    get {
    set {


interface IDoNotUseAllFixedProperties {

    [...] PropertyWhichIsNotShownInProperties { get; set; }


The implementation is divided into initialization and handling.

The initialization-methods are protected, so they could only be called by descendants (never mind Reflection). It is possible to choose different types of initialization (I hope the signature is self-explaining).

protected virtual void initializeValueOf(String Key_, 
                                         Object Value_) {

protected virtual void initializeValueOf(String  Key_, 
                                         Object  Value_, 
                                         Boolean CreateKeyValuePair_) {


protected virtual void initializeValueOf(String  Key_, 
                                         Object  Value_, 
                                         Boolean CreateKeyValuePair_, 
                                         Boolean AsReadOnly_) {

It is also possible to initialize fixed-properties, if necessary. Also nothing too fancy.

The handling of the properties is a little bit more tricky, but all in all very straightforward.

Using the code

It is necessary to inherit a class from AbstractObjectWithProperties. An inherited class could have fixed properties or initialize different Key-Value pairs.

public class MyClass : AbstractObjectWithProperties {

    public MyClass() {

        this.initializeValueOf("ID",         Guid.NewGuid(), true, true);
        this.initializeValueOf("Property 1", String.Empty,   true);
        this.initializeValueOf("Property 2", String.Empty,   true);

    public Guid ID {
        get { 
            return this.getValueOf<Guid>("ID"); 

    public String Property_1 {
        get {
            return this.getValueOf<String>("Property 1");
        set {
            this["Property 1"] = value;

    public String Property_2 {
        get {
            return this.getValueOf<String>("Property 2");
        set {
            this["Property 2"] = value;

For examples, just look into the demo code.

Points of Interest

The first problem I encountered was that unfortunately there is no common method to parse values, but this would be necessary for initialization of values to provide type-safety, so I decided to create a common interface which would allow me to parse values without thinking about the conversion of a real type.

To create a converter or parser, you call the factory with the type you would like to convert. (Right now, there are only six converters available, but expanding should not be a problem.)

The code is included but not explained.

If you are using a different MEMBER_PREFIX than "_", you should change it in the class AbstractObjectWithProperties. Same for MEMBER_BINDINGFLAGS.

/// <summary>
/// Member-prefix should be customized... if necessary...
/// </summary>
protected static String       MEMBER_PREFIX = "_";
protected static BindingFlags MEMBER_BINDINGFLAGS = 
          BindingFlags.Instance | BindingFlags.NonPublic;

protected virtual FieldInfo getFieldInfo(String Key_) {

    FieldInfo   result      = null;
    Type        contextType = this.GetType();

    while ((contextType != null) && (result == null)) {
        result      = contextType.GetField(MEMBER_PREFIX + Key_, MEMBER_BINDINGFLAGS);
        contextType = contextType.BaseType;

    return result;

There are some drawbacks. I would especially recommend the article of M. Fowler: Dealing with Properties. This isn't a silver bullet, so don't use it as one.

  • Dynamic add or remove of a property isn't possible out-of-the-box... but could be added if required.
  • Properties not wrapping a field can not be used.
  • A property whose value is computed at runtime is not possible.
  • Casting is (currently) not possible (sorry, lack of an idea).


  • 25 April, 2011
    • Added a method to check equality of the type of a given key and a value.
  • 20 February, 2011
    • Attribute added to prevent showing fixed-properties.
    • Derive from MarshalByRefObject by preprocessor.
  • 05 September, 2010
    • Initial version.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Germany Germany
- Born at the dawn of the Video Game Consoles
- Hacked his way through a C64 by Assembler
- Survived the hard times with an Amiga
- Got hit by Delphi on PC in the mid-90s
- Sinned with VB6
- Redeemed by C++ and C#

You may also be interested in...

Comments and Discussions

GeneralInteresting approach Pin
Erion Pici28-Feb-11 21:59
memberErion Pici28-Feb-11 21:59 
GeneralRe: Interesting approach Pin
s_mon1-Mar-11 9:17
members_mon1-Mar-11 9:17 
GeneralMy vote of 1 Pin
Paulo Zemek24-Feb-11 3:18
memberPaulo Zemek24-Feb-11 3:18 
GeneralRe: My vote of 1 Pin
s_mon25-Feb-11 0:31
members_mon25-Feb-11 0:31 
Paulo Zemek wrote:
I honestly didn't understand why you need to iterate through properties without using reflection and, then, you use reflection for another purpose.

Internally I use reflection; externally not...

Paulo Zemek wrote:
Wouldn't it be easier to simple inherit from a dictionary, then use property getters/setters to read/write directly to the dictionary values and, maybe, add some checks to see if a property is read-only?

That was my first thought; and I implemented it in this way in the first place... but some of the "Dynamic Properties" (don't like the term) should also be read only... so this didn't solve my problem.

Paulo Zemek wrote:
Also, I don't see the type-safety, as calling getValueOf with the wrong type is the same as doing (Type)getValueOf(...).

Right... as any other type that is casted from object... I need the type-safety in setting a value. I admit, the method to get a type for a certain key should be public to avoid an exception (Thanks for the thoughtThumbs Up | :thumbsup: ).

Paulo Zemek wrote:
The code look too java for me. In .Net, methods are capitalized from the first word.

Yeah, the world is a bad place Wink | ;)

No offense taken for the 1... always a challenge for getting betterThumbs Up | :thumbsup:

Generaluserfull Pin
Pranay Rana24-Feb-11 3:02
memberPranay Rana24-Feb-11 3:02 
QuestionWhy not a dictionary? Pin
maspr7-Sep-10 23:57
membermaspr7-Sep-10 23:57 
AnswerRe: Why not a dictionary? Pin
s_mon8-Sep-10 9:33
members_mon8-Sep-10 9:33 
GeneralVery Good .. Pin
Sushant Joshi6-Sep-10 7:12
memberSushant Joshi6-Sep-10 7:12 
GeneralRe: Very Good .. Pin
s_mon7-Sep-10 6:43
members_mon7-Sep-10 6:43 
GeneralMy vote of 5 Pin
Eric Xue (brokensnow)5-Sep-10 12:03
memberEric Xue (brokensnow)5-Sep-10 12:03 
GeneralRe: My vote of 5 Pin
s_mon5-Sep-10 21:24
members_mon5-Sep-10 21:24 
QuestionWhy? Pin
zlezj5-Sep-10 10:23
memberzlezj5-Sep-10 10:23 
AnswerRe: Why? Pin
Eric Xue (brokensnow)5-Sep-10 12:05
memberEric Xue (brokensnow)5-Sep-10 12:05 
AnswerRe: Why? Pin
s_mon5-Sep-10 21:23
members_mon5-Sep-10 21:23 
GeneralRe: Why? Pin
Kubajzz8-Sep-10 11:28
memberKubajzz8-Sep-10 11:28 
GeneralRe: Why? Pin
s_mon14-Sep-10 22:47
members_mon14-Sep-10 22:47 
GeneralRe: Why? Pin
JV999924-Feb-11 0:48
memberJV999924-Feb-11 0:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180111.1 | Last Updated 25 Apr 2011
Article Copyright 2010 by StM0n
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid