Ayende @ Rahien

Hi!
My name is Ayende Rahien
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

@

Posts: 5,949 | Comments: 44,546

filter by tags archive

C# Coding Challenge: What will this code do?


What is the output of this code?

 IDictionary<object,string> instanceToKey = new Dictionary<object, string>();

 IDictionary<string, int> keyToCost = new Dictionary<string, int>();

 var inst1 = new object();
 var inst2 = new object();

 instanceToKey[inst1] = "one";
 keyToCost["one"] = 1;

 instanceToKey[inst2] = "two";
 keyToCost["two"] = 2;

 string value = null;
 foreach (var key
     in (from inst in new[]{inst1, inst2, new object()}
         where instanceToKey.TryGetValue(inst, out value) 
         select value))
 {
     int cost;
     if(keyToCost.TryGetValue(key, out cost))
         Console.WriteLine("Key: {0}, Cost: {1}", key, cost);
 }

Comments

Steve Py

Well it's bloody convoluded, but I couldn't see anything wrong with it. The 3rd instance will be ignored because of the TryGetValue.

Key: One, Cost: 1

Key: Two, Cost: 2

I thought you might have a gotcha in there so I also tried it in .Net 3.5 and 4.0 but got the same result... Is something missing?

Ken Egozi

Am I missing something? it should be the trivial "one"/1 and "two"/2 pairs

dan
dan

haven't touched .net for a while, but inst1 and inst2 are both new object() - will they have identical hash codes for the dictionary?

if so, the result will be:

Key: two, Cost: 2

Key: two, Cost: 2

Key: two, Cost: 2

Glenn

+1 to Steve's comment. TryGetValue returns false for the 3rd object and it's never selected.

kukabuka

I was going to agree with dan, but if you run the code it is just

Key: One, Cost: 1

Key: Two, Cost: 2

inst1.Equals(inst2) = false. .GetHashCode() will reveal different hashes too. I guess that makes the difference to the Dictionary type.

rvin100

I'm agree with Steve too. It's a strange way to process, but you just got :

Key: One, Cost: 1

Key: Two, Cost: 2

The third instance is just ignored...

Ayende Rahien

This is actually what I call a reverse gotcha.

It works as you expect it to, but it doesn't look like it will work.

Stefan Wenig

Sweet! Code that relies on delayed execution, string interning and the semantics of mutating captured variables. That's much better than last time's prefix decrement operator!

Next time, can we have some lock-free multi-threaded code along with the question "what will this code print on an Itanium system?"

Please! ;-) (you might need to specify the chipset though, but then at least participants can't just run the code to solve the quiz!)

Omer Mor

Why doesn't it look like it will work?

Looking at the code, it seemed just fine to me.

Felipe Fujiy

GetHashCode for classes by default return a unique token by instannce

Andrey Titov

I'd rewrite this in something like:

foreach (var keyCost in

new[] { inst1, inst2, new object() }

.ApplyMap(instanceToKey, (inst, key) => key)

.ApplyMap(keyToCost, (key, cost) => new { key, cost }))

{

Console.WriteLine("Key: {0}, Cost: {1}", keyCost.key, keyCost.cost);

}

public static IEnumerable <tresult ApplyMap <tresult,> (

this IEnumerable

<tsource source,

Func

<tsource,> keySelector,

IDictionary

<tkey,> map,

Func

<tsource,> resultSelector

)

{

foreach (var item in source)

{

    TKey key = keySelector(item);

    TValue value;

    if (map.TryGetValue(key, out value))

    {

        yield return resultSelector(item, key, value);

    }

}

}

TryGetValue() newer fit well in LINQ :-(

Andrey Titov

I forgot second overload:

public static IEnumerable <tresult ApplyMap <tresult,> (

this IEnumerable

<tsource source,

IDictionary

<tsource,> map,

Func

<tsource,> resultSelector

)

{

return ApplyMap(source, key => key, map, (item, key/*=item*/, value) => resultSelector(item, value));

}

Steve Py

"This is actually what I call a reverse gotcha.

It works as you expect it to, but it doesn't look like it will work. "

rofl... Intentionally making something more obscure than it needs to be? That whole debate over Raven DB licensing must have put you in that sort of mood. ;)

Daniel

To everyone who thinks the is working correctly: change the order in the array so that the 3rd instance is in the middle:

new[]{inst1, new object(), inst2}

Then try to explain out why changing the position of an element that seems to be ignored changes the output of the program.

configurator

Daniel: I don't see why it would. And it doesn't.

meisinger

Thats funny... have what is called "reverse reverse gotchas" all over the place

Code that looks like it shouldn't work and doesn't work

(oh I love the double negative)

I haven't checked but I am pretty sure that I can also produce just the simple "gotcha"

Code that looks like it should work but doesn't work

fschwiet

well the loop input

from inst in new[]{inst1, inst2, new object()} where instanceToKey.TryGetValue(inst, out value) select value

is equivalent to:

new[] {inst1, inst2, new object()}.Where(inst => instanceToKey.TryGetValue(inst, out value)).Select(

                inst => value)

I assumed this was equivalent to

new[] {inst1, inst2, new object()}.Where(inst => instanceToKey.TryGetValue(inst, out value)).ToArray().Select(

                inst => value)

But its not. So I was all sorts of wrong.

Diego Mijelshon

"It works as you expect it to, but it doesn't look like it will work." -> which is why it's important to write the tests first. If it passes, you don't need to code anything else.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. The RavenDB Comic Strip: Part III – High availability & sleeping soundly - 5 hours from now

There are posts all the way to May 28, 2015

RECENT SERIES

  1. The RavenDB Comic Strip (3):
    20 May 2015 - Part II – a team in trouble!
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats