2

I have seen this, but I am wondering if it would be possible to force the override of a member not marked as virtual or abstract with a derived type (hence that should not break the base object functionalities).

I am referring in particular to overriding:

IDictionary<TKey, TValue> Dictionary { get; }

in

KeyedCollection<TKey, TValue> 

with another member type that implements IDictionary, to use another internal storage collection.

Is it possible at all to bypass the limitation?

Note that I would not like to use extensions for this (in my case it would not be helpful anyway).

Community
  • 1
  • 1
Erwin Mayer
  • 18,076
  • 9
  • 88
  • 126
  • 1
    You've conceded that you cannot override something non-virtual, you can merely hide, so you're asking if you can *force overriding of something non-virtual?* If you can't do A, you certainly can't *force* A. – Anthony Pegram Sep 14 '11 at 23:38
  • 1
    If you 've read that other question, in what way is yours different so that you don't already know the answer? – Jon Sep 14 '11 at 23:39
  • If you're **forcing** override, what's the point of avoiding `virtual`/`abstract`? – Matt Ball Sep 14 '11 at 23:39
  • @Jon, the other question did not provide insight about the possibility to physically force the override (by whatever means, for example using Reflection). – Erwin Mayer Sep 14 '11 at 23:40
  • @Matt: I am not trying to avoid virtual/abstract, but since the member I need to override is not marked as virtual/asbtract, I am looking at ways to circumvent this restriction. – Erwin Mayer Sep 14 '11 at 23:42
  • 1
    @ErwinMayer: Maybe Anthony states it better: you know that you cannot *do* X. How would it be possible to *force* it, which goes one step further? – Jon Sep 14 '11 at 23:44
  • Erwin, what problem (*business* problem, not virtual/abstract problem) are you actually needing to solve? Perhaps someone can point you in a direction that is *not* an attempt to do what the language does not allow. – Anthony Pegram Sep 14 '11 at 23:50
  • @Jon: By "forcing" I mean trying to circumvent the impossibility; maybe it is a false friend with "forcer" in French :). – Erwin Mayer Sep 14 '11 at 23:55
  • @Anthony I would like to replace the Dictionary in the GenericKeyedCollection with another version that uses a memory-mapped file, for use with large datasets. I understand that it makes full sense to prevent developer from overriding Dictionary with a member that would not implement IDictionary, but in my case it would not break the functionality of the base class. – Erwin Mayer Sep 14 '11 at 23:59

3 Answers3

5

No- in .net a method must be marked as explicitly virtual or abstract to override it.

EDIT: Given the edits to the question, it sounds like you need to create a custom class that implements IDictionary<TKey, TValue> (which I think KeyedCollection does), then add another indexer that allows you to get objects by TKey. The indexer would look like this:

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

If you want, you can back virtually all of the IDictionary methods and properties by delegating to a private KeyedCollection<TKey, TValue> field, and for those you want to implement differently you'd be free to do so. The full class would be too long for an answer, otherwise I'd post it.

This goes toward the good development practice Prefer Composition over Inheritance

Community
  • 1
  • 1
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • So you mean I should entirely rewrite KeyedCollection; is there a way to access the original implementation rather than decompiling (when going to the definition I can see the members, but not their content)? – Erwin Mayer Sep 15 '11 at 12:14
  • 1
    If you are rewriting KeyedCollection you are probably doing it wrong. KeyedCollection inherits Collection, so you can do the same. If you explicitly need a KeyedCollection (because you are passing it to a method that expects one, and you cannot change that method) then you are stuck- nothing you do will make that other method call your Dictionary property. If on the other hand you are just using it in your code, you should implement all of the same methods that KeyedCollection does, and defer to a private KeyedCollection inside of your class for the ones you don't want to change. – Chris Shain Sep 15 '11 at 14:39
3

If .NET is like c++ regarding this, that won't be physically possible, since virtuals are implemented as pointers to functions, and non-virtuals as fixed function addresses.

So, NO.

Even if you meddle with reflection or pointers or whatever, you don't have a PLACE for putting new function pointer since virtual/abstract reserves it.

Maybe it will be the best for you to see disassembled code - see how virtuals are called and compare to how non-virtuals are called.

Daniel Mošmondor
  • 19,718
  • 12
  • 58
  • 99
0

As other answers have said, you cannot override in the derived class, but you can hide the base implementation:

static void Main(string[] args)
{
    Console.WriteLine("Animal: {0}", new Animal().NumberOfLegs);
    Console.WriteLine("Caterpillar: {0}", new Caterpillar().NumberOfLegs);

    Console.ReadKey();
}

public class Animal
{
    public int NumberOfLegs { get { return 1; } }
}

public class Caterpillar : Animal
{
    public new int NumberOfLegs { get { return 100; } }
}
slugster
  • 49,403
  • 14
  • 95
  • 145
  • 1
    Thanks, yes I know, but unfortunately if the collection is cast as the base class, the base members will be used. – Erwin Mayer Sep 15 '11 at 12:08