Overriding Dictionary Not Found Exception

G

Guest

Is it possible to override the behaviour of a dictionary if an object is not
found?

string ss=null;
Dictionary<string, string> dict = new Dictionary<string,
string>();

// method 1

try { ss = dict["x"]; }
catch (KeyNotFoundException) {/* Ignore */}

// method 2

if (dict.ContainsKey("x")) ss = dict["x"];

In Method 1, if the key is not there then we have the considerable overhead
of an Exception.
In Method 2 it looks as though we need two dictionary scans.

So is it possible to change the default behaviour of a dictionary so it
returns a null value if not found rather than throwing the exception?
 
A

Anders Borum

Hello!

The Dictionary class is not sealed, so you could create a new concrete
Dictionary with the new functionality. The indexer is not marked virtual, so
you would have to use the "new" keyword when defining the new indexer (you
should make sure that all apropriate methods are re-implemented to ensure
the null-behaviour you're looking for).

Another approach would be to use the Dictionary.TryGetValue() method instead
and adapt your client code to the default non-null behaviour.
 
J

Jon Skeet [C# MVP]

Is it possible to override the behaviour of a dictionary if an object is not
found?

string ss=null;
Dictionary<string, string> dict = new Dictionary<string,
string>();

// method 1

try { ss = dict["x"]; }
catch (KeyNotFoundException) {/* Ignore */}

// method 2

if (dict.ContainsKey("x")) ss = dict["x"];

In Method 1, if the key is not there then we have the considerable overhead
of an Exception.
In Method 2 it looks as though we need two dictionary scans.

So is it possible to change the default behaviour of a dictionary so it
returns a null value if not found rather than throwing the exception?

You could use Dictionary.TryGetValue - it looks like that's what you're
after.

From a pragmatic (but not elegant) point of view, are you sure that
catching the exception *actually* incurs an overhead which is
significant in your application? You might be surprised just how cheap
exceptions are. See
http://www.pobox.com/~skeet/csharp/exceptions.html for some discussion
on this. I only mention this because many people have bought into the
mantra of "exceptions are expensive" without really looking into it.
 
J

Jesse McGrew

You can use TryGetValue instead.

string ss=null;
Dictionary<string, string> dict = new Dictionary<string,
string>();

if (dict.TryGetValue("x", out ss) == true) {
/* the key was found, and ss now contains the value */
} else {
/* the key wasn't found, and ss is null */
}

Jesse
 
G

Guest

To All Above... Thanks - next time I will read ALL the methods before
posting. (As an excuse - it IS the last one in the method list :)

To Anders Borum.. TryGetValue is what I need, but I'll give yours a go as a
learning exercise.
 
I

Ignacio Machin \( .NET/ C# MVP \)

HI,

Jon Skeet said:
I only mention this because many people have bought into the
mantra of "exceptions are expensive" without really looking into it.

I will read you article, but regarding the cost of an exception IIRC even
MS offer that view , that exception are expensive.
 
C

Chris Dunaway

Jon said:
http://www.pobox.com/~skeet/csharp/exceptions.html for some discussion
on this. I only mention this because many people have bought into the
mantra of "exceptions are expensive" without really looking into it.

Very interesting article. My experience has been that the *first* time
an exception is thrown it seems to take a few seconds (presumably
because it has to jit compile the assembly that contains the exception
type), but after that, if the *same* exception is thrown there is
practically no performance hit.

I wonder if there is a way to "pre-load" the exception types during the
start up of the app or is it even worth doing it.
 
J

Jon Skeet [C# MVP]

Chris Dunaway said:
Very interesting article. My experience has been that the *first* time
an exception is thrown it seems to take a few seconds (presumably
because it has to jit compile the assembly that contains the exception
type), but after that, if the *same* exception is thrown there is
practically no performance hit.

I wonder if there is a way to "pre-load" the exception types during the
start up of the app or is it even worth doing it.

Have you experienced that when running a release build not in the
debugger? Do you have a complete program which demonstrates that? I've
only seen that happen in the debugger, which is a very different
situation.
 
J

Jon Skeet [C# MVP]

<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us> said:
I will read you article, but regarding the cost of an exception IIRC even
MS offer that view , that exception are expensive.

They're expensive if you're going to end up throwing them thousands and
thousands of times per second - otherwise they're almost always lost in
the noise.

As for whether or not to just follow MS's advice - I tend to trust the
evidence of my own eyes above MSDN. After all, it was only after
badgering them for quite a while that MSDN was changed to admit that
System.Decimal was a floating point type. (It had previously been
inaccurately described as a fixed point type.) MS are just as capable
of making mistakes as the rest of us :)
 
R

rossum

Jon wrote:
[snip]

I wonder if there is a way to "pre-load" the exception types during the
start up of the app or is it even worth doing it.

Presumably you could explicitly throw it yourself:

try {
throw new myPreLoadException();
}
catch (myPreLoadException) { /* Do nothing */ }

Whether it is worth doing is another question.

rossum
 

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