Overriding Dictionary Item method

A

Arthur Dent

Hello all... I have a class which inherits from the Generic Dictionary
class.
I want to "override" the Item property. I know it is not technically
Overridable, so I marked my property as "Shadows".

Here is the relevant code...

Public Class MyClass
Inherits Dictionary(Of String, Integer)

Shadows Property Item(ByVal key As String) As Double
Get
Return If Not Me.ContainsKey(key) Then Me.Add(key, 0)
Return MyBase.Item(key)
End Get
Set(ByVal value As Double)
If Not Me.ContainsKey(key) Then Me.Add(key, 0)
MyBase.Item(key) = value
End Set
End Property
End Class

Basically, I just want that if a non-existent key is queried, it returns 0
instead of throwing an exception.
But if I run something like
Debug.Print(myClassInstance("123"))
where "123" is not a valid key, is stills throws an exception instead of
returning 0.
It throws "The given key was not present in the dictionary."

I tried adding the following attribute to my class, but it didn't help...
<DefaultProperty("Item")>

Thanks in advance, ... A.D.
 
P

Peter Duniho

[...]
Basically, I just want that if a non-existent key is queried, it returns
0 instead of throwing an exception.
But if I run something like
Debug.Print(myClassInstance("123"))
where "123" is not a valid key, is stills throws an exception instead of
returning 0.
It throws "The given key was not present in the dictionary."

What happens if you change your Item property to be an Integer instead of
Double?

I don't know VB well enough to fully understand your code example (the
multiple "Return" statements in the getter definitely have me confused :)
), but I can well imagine that the compiler is seeing two different Item
methods, and arbitrarily is choosing the one returning an Integer instead
of the one returning a Double you've declared.

My personal opinion is that what you're doing is pretty fragile anyway.
IMHO it would be better to define a more explicit method that does what
you're looking for and call that when necessary. After all, any code that
uses this is necessarily going to need to be written with the
shadowing/hiding in mind anyway; you might as well make it explicit to
avoid any maintenance hassles in the future.

Pete
 
A

Arthur Dent

Thanks for the quick reply Peter! :)

Yes, actually, the "double return" was a mis-type by me in the post... what
the code ACTUALLY is, is this:

Shadows Property Item(ByVal key As String) As Double
Get
Return If(Me.ContainsKey(key), MyBase.Item(key), 0)
End Get
Set(ByVal value As Double)
If Not Me.ContainsKey(key) Then Me.Add(key, 0)
MyBase.Item(key) = value
End Set
End Property

Actually, I figured out what was necessary to get it to properly shadow...

As opposed to declaring my class as so...
<DefaultProperty("Item")> Public Class MyClass

I had to alter the definition of my shadowing property to
Default Property Item(ByVal key As String) As Double ...

So there is apparently something different in the way the compile reads
"<DefaultProperty("Item")>" vs. "Default Property Item".

No we know; and knowing is half the battle! ;)
 
C

Cowboy \(Gregory A. Beamer\)

A potentially better method, depending on your particular problem domain, is
to create a method that queries a property that is named something other
than Item(). In fact, most of the .NET classes already have this method,
known as Contains(). So, in your code, the method for safe coding is
something like:

If (dict.Contains(key)) Then
Return dict.Item(key)
Else
Return 0
End If

By abstracting the access to the dictionary with a method that does the
above (or similar), you end up with safe code without overwriting expected
functionality of the underlying .NET class.

This does not mean you should never Shadow, but shadowing should be done
only in exceptional cases, not as a means of solving a problem that can be
solved via safe coding practices.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

*************************************************
| Think outside the box!
|
*************************************************
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top