views:

81

answers:

4

Suppose I have some extension methods but also need to extend the object's state. Seeing as there is no support for extension properties in C#, would using shared static Dictionary be a good solution?

For example something like this:

class Foo
{
        // 3rd party class
}

static class Helper
{
    private static Dictionary<Foo, Guid> guidDict = new Dictionary<Foo, Guid>();

    public static void DoSomething(this Foo foo)
    {
        Guid guid = guidDict[foo];
        // do stuff
    }

    public static void DoAnotherthing(this Foo foo)
    {
        Guid guid = guidDict[foo];
        // do stuff
    }

}

What are some other solutions?

+1  A: 

You are correct in that you cannot maintain state with extension methods, but nor would you be able to with extension properties. They can only manipulate state in ways that you would otherwise have access to anyway.

However, I don't believe a static Dictionary will help either. It would be good possibly for maintaining shared state, but not an object's state. Are you doing something fancy like the following? There is a good unique identifier on each instantiated object, such that you could add a state variable to the dictionary that would be keyed to that object? That seems kindof round-about, if that's what you're attempting

Assuming you have no control over the class itself (hence the need to extend it in some way), can you inherit from this object? Then of course you can do what you need to do.

Patrick Karcher
Yes, not having to extend the base class was my aim. But a lot issues surrounding dictionaries posted here are very valid. I just hope they add the support for extension properties soon.
Dan7
The Decorator pattern mentioned by Jason is something to consider. If you're like me you might roll your eyes at pattern-based advice (patterns are often used instead of actual thinking), but in this case take a look. It's not just being able to apply inheritance at run time, but being able to apply it to **already existing objects**. If that's why inheritance seems not good to you in this situation, Decorator addresses that.
Patrick Karcher
So far Decorator pattern is the closest to my original intent without the issues mentioned above. Thanks guys.
Dan7
+3  A: 

I'm not sure that is a good idea; the synchronization would be a nightmare, and you'd need to use a key that didn't risk keeping all the objects alive forever (don't use the object-reference). Better to use a property bag inside the object, or wrap your object in something else that provides the missing properties. You could also use inheritance, but that has more limitations (you can encapsulate a sealed type or an interface). You can forward the members if you really want:

public class Foo {
    private readonly Bar bar;
    public Foo(Bar bar) { this.bar = bar; }


    public int Id { get {return bar.Id; } set {bar.Id = value; } }
    public string Name {get;set;}
}
Marc Gravell
Could you elaborate more on why object-reference should be avoided?
Dan7
@Shizhidi - because the static dictionary would keep on holding them, even if every other reference has gone. Your objects would never be collected.
Marc Gravell
Ah gottcha, thanks!
Dan7
+1  A: 

If you need to extend an object's state then I'd recommend inheritance or composition.

LukeH
Yeah I thought about both too but I was wondering if I could continue using the base classes.
Dan7
+1  A: 

What's wrong with the usual solution of inheriting or object composition (decorator pattern) to add the properties that you need?

Would using shared static Dictionary be a good solution?

I don't think so. Aside from synchronization issues and global state issues, you also have ugly object lifetime issues:

{
    MyObject o = new MyObject();
    PropertyDictionary.Add(o, "SomeExtensionProperty", someValue);
} 

Now o is out of scope but the dictionary still has a reference to it! Yucky!

Jason
Haven't thought about that. Good one! It definitely makes a strong case for avoiding dictionaries.
Dan7
@Downvoter: Please explain.
Jason