6

I have a special type of dictionary. I'm not sure how to do this exactly, but I'm looking to make the get method virtual, but not the set method:

    public TValue this[TKey key]
    {
        get { ... }
        set { ... }
    }

Is it possible and if so what is the correct combination?

myermian
  • 31,823
  • 24
  • 123
  • 215
  • What do you want to achieve by making only the getter `virtual`? There might be a better way to do that. – Frédéric Hamidi Jul 11 '11 at 19:52
  • Just trying to make it possible to extend my "ReadOnlyDictionary". Because it is a read-only dictionary I don't support the set method (throws an exception), but an extending class might want to perform additional work from the get method, hence they could override it and work modify it. – myermian Jul 11 '11 at 19:54
  • Than you should not try to make "get" method virtual, but instead have some virtual "OnGetCalled" method and let derived class to override it. Derived class will not be able to override "get" (i.e. by Mark's suggestion) without calling Base version, so separate method will make the contract explicit. – Alexei Levenkov Jul 11 '11 at 20:04

4 Answers4

14

You can't do that directly - you would need to add a separate method:

protected virtual TValue GetValue(TKey key) { ...}

public TValue this[TKey key]
{
    get { return GetValue(key); }
    set { ... }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Nevermind, my fault. Sorry. The solution I had in mind obviously made the setter private. Still, if the collection is readonly I do not see the problem in that but its a different solution. – InBetween Jul 11 '11 at 20:03
6

Sorry... There is no syntax for doing this in C#, but you can do this instead.

public TValue this[TKey key]
{
   get { return GetValue(key) }
   set { ... }
} 

protected virtual TValue GetValue(TKey key)
{
   ...
}
agent-j
  • 27,335
  • 5
  • 52
  • 79
1

I might be misunderstanding something but if your Dictionary is going to be readonly you have to implement a wrapper to ensure it is really readony (the dictionary's indexed property is not virtual so you can't override its behavior) in which case you can do the following:

public class ReadOnlyDictionary<TKey, TValue>
{
    Dictionary<TKey, TValue> innerDictionary;

    public virtual TValue this[TKey key]
    {
        get
        {
            return innerDictionary[key];
        }
        private set
        {
            innerDictionary[key] = value;
        }
    }
}
InBetween
  • 32,319
  • 3
  • 50
  • 90
0

I'm assuming what you're trying to do here is create a situation where they have to define how the property is read but not how the property is set?

This strikes me like a bad idea. You could have a setting setting the value of _myVar but the end-developer constructing a getter that that reads _someOtherVar. That said, I don't know what your use case is, so it is very likely I'm missing something.

Regardless, I think this prior question might help: Why is it impossible to override a getter-only property and add a setter?

Community
  • 1
  • 1
Marc LaFleur
  • 31,987
  • 4
  • 37
  • 63