By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,148 Members | 739 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,148 IT Pros & Developers. It's quick & easy.

Generic IDictionary confusion

P: n/a
trying to design an effiecient interface, where I can pass an
IDictionary<int,string^to a method. int is some id and string^ is
some
value that is initialized to null by a caller.

The callee function needs to update the value based on the key.

in native code I'd have passed a std::map and do ((*it).second) = new
std::string("test");

I don't see a way to do it in managed code.

I obviously can't assign it to keyValuePair element as it's read only.
And I can't even do this:

for each ( KeyValuePair<int, string^>^ iter in testCollection )
{
testCollection[iter->key] = "test"
}

as on the second pass of the loop, the code above will throw since the
colleciton is modified.

Thus, it looks like I need 2 passes, where I'd make a list of ids in
the first pass and on the second pass, I'd do something
like:
for ( int i = 0; i < ListIds.Count; ++i )
{
testCollection[listIds[i]] = "test";
}

This code seems very poor. Is there really no way to update the
IDictionary<key,valuein 1 pass? I've got to be missing some
IEnumerator that would let me do that :)

Thanks in advance!
vcq

Sep 14 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
On Sep 13, 10:45 pm, vcquestions <vcquesti...@gmail.comwrote:
trying to design an effiecient interface, where I can pass an
IDictionary<int,string^to a method. int is some id and string^ is
some
value that is initialized to null by a caller.

The callee function needs to update the value based on the key.

in native code I'd have passed a std::map and do ((*it).second) = new
std::string("test");

I don't see a way to do it in managed code.

I obviously can't assign it to keyValuePair element as it's read only.
And I can't even do this:

for each ( KeyValuePair<int, string^>^ iter in testCollection )
{
testCollection[iter->key] = "test"

}

as on the second pass of the loop, the code above will throw since the
colleciton is modified.

Thus, it looks like I need 2 passes, where I'd make a list of ids in
the first pass and on the second pass, I'd do something
like:
for ( int i = 0; i < ListIds.Count; ++i )
{
testCollection[listIds[i]] = "test";

}

This code seems very poor. Is there really no way to update the
IDictionary<key,valuein 1 pass? I've got to be missing some
IEnumerator that would let me do that :)

Thanks in advance!
vcq
any suggestions?

Sep 14 '07 #2

P: n/a

"vcquestions" <vc*********@gmail.comwrote in message
news:11*********************@57g2000hsv.googlegrou ps.com...
trying to design an effiecient interface, where I can pass an
IDictionary<int,string^to a method. int is some id and string^ is
some
value that is initialized to null by a caller.

The callee function needs to update the value based on the key.

in native code I'd have passed a std::map and do ((*it).second) = new
std::string("test");

I don't see a way to do it in managed code.

I obviously can't assign it to keyValuePair element as it's read only.
And I can't even do this:

for each ( KeyValuePair<int, string^>^ iter in testCollection )
{
testCollection[iter->key] = "test"
}

as on the second pass of the loop, the code above will throw since the
colleciton is modified.
You could file a bug against this, as it's improper behavior. Iterators
should only be invalidated when the morphology (shape) of the collection
changes, and updating a value doesn't do that. The version number
increment, which is causing that exception, should only be done when an item
is added or removed.

BTW KeyValuePair is a value type, so you shouldn't use ^ with it (doing so
isn't outright wrong, but it does slow you down because of boxing and
unboxing).
>
Thus, it looks like I need 2 passes, where I'd make a list of ids in
the first pass and on the second pass, I'd do something
like:
for ( int i = 0; i < ListIds.Count; ++i )
{
testCollection[listIds[i]] = "test";
}

This code seems very poor. Is there really no way to update the
IDictionary<key,valuein 1 pass? I've got to be missing some
IEnumerator that would let me do that :)

Thanks in advance!
vcq
Sep 14 '07 #3

P: n/a
On Sep 14, 12:56 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
"vcquestions" <vcquesti...@gmail.comwrote in message

news:11*********************@57g2000hsv.googlegrou ps.com...


trying to design an effiecient interface, where I can pass an
IDictionary<int,string^to a method. int is some id and string^ is
some
value that is initialized to null by a caller.
The callee function needs to update the value based on the key.
in native code I'd have passed a std::map and do ((*it).second) = new
std::string("test");
I don't see a way to do it in managed code.
I obviously can't assign it to keyValuePair element as it's read only.
And I can't even do this:
for each ( KeyValuePair<int, string^>^ iter in testCollection )
{
testCollection[iter->key] = "test"
}
as on the second pass of the loop, the code above will throw since the
colleciton is modified.

You could file a bug against this, as it's improper behavior. Iterators
should only be invalidated when the morphology (shape) of the collection
changes, and updating a value doesn't do that. The version number
increment, which is causing that exception, should only be done when an item
is added or removed.

BTW KeyValuePair is a value type, so you shouldn't use ^ with it (doing so
isn't outright wrong, but it does slow you down because of boxing and
unboxing).


Thus, it looks like I need 2 passes, where I'd make a list of ids in
the first pass and on the second pass, I'd do something
like:
for ( int i = 0; i < ListIds.Count; ++i )
{
testCollection[listIds[i]] = "test";
}
This code seems very poor. Is there really no way to update the
IDictionary<key,valuein 1 pass? I've got to be missing some
IEnumerator that would let me do that :)
Thanks in advance!
vcq- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Thanks Ben! On the iteration ( 1-st question ) do you see a clean
workaround ( a different method of iterating through collection &
updating values )?
Also, thanks for pointing out the KeyValuePair issue!

Sep 14 '07 #4

P: n/a
>>
Thanks in advance!
vcq- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Thanks Ben! On the iteration ( 1-st question ) do you see a clean
workaround ( a different method of iterating through collection &
updating values )?
Also, thanks for pointing out the KeyValuePair issue!
As I said, I think it is a bug in the BCL Dictionary<TKey,TValue>::Insert
helper function. There are two code paths, one for when the key already
exists, and one where it does not. The first of those should not increment
the private version variable which effectively kills all existing
enumerators.

If you submit a bug on Connect, post the link here. I will validate it and
vote for it.

Sep 14 '07 #5

P: n/a
On Sep 14, 1:21 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
Thanks in advance!
vcq- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -
Thanks Ben! On the iteration ( 1-st question ) do you see a clean
workaround ( a different method of iterating through collection &
updating values )?
Also, thanks for pointing out the KeyValuePair issue!

As I said, I think it is a bug in the BCL Dictionary<TKey,TValue>::Insert
helper function. There are two code paths, one for when the key already
exists, and one where it does not. The first of those should not increment
the private version variable which effectively kills all existing
enumerators.

If you submit a bug on Connect, post the link here. I will validate it and
vote for it.
I got the bug part - I just refused to believe that MSFT gives us such
pleasant surprises -:) ( but after Debug::Assert( 0 ) showing up in
release mode - oh well... )

here's the link:
https://connect.microsoft.com/Visual...dbackID=298166

Sep 14 '07 #6

P: n/a

"vcquestions" <vc*********@gmail.comwrote in message
news:11**********************@57g2000hsv.googlegro ups.com...
On Sep 14, 1:21 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
Thanks in advance!
vcq- Hide quoted text -
>- Show quoted text -- Hide quoted text -
>- Show quoted text -
Thanks Ben! On the iteration ( 1-st question ) do you see a clean
workaround ( a different method of iterating through collection &
updating values )?
Also, thanks for pointing out the KeyValuePair issue!

As I said, I think it is a bug in the BCL Dictionary<TKey,TValue>::Insert
helper function. There are two code paths, one for when the key already
exists, and one where it does not. The first of those should not
increment
the private version variable which effectively kills all existing
enumerators.

If you submit a bug on Connect, post the link here. I will validate it
and
vote for it.

I got the bug part - I just refused to believe that MSFT gives us such
pleasant surprises -:) ( but after Debug::Assert( 0 ) showing up in
release mode - oh well... )

here's the link:
https://connect.microsoft.com/Visual...dbackID=298166
They appear to be hiding behind "It's not wrong, because we choose to define
the correct behavior as the way it works". I've added a bunch of counter
examples -- in C++/CLI -- to the bug report in the hope that somebody
realizes that there's value in having .NET collections act the same way
every other collection in the world does.

Sep 28 '07 #7

P: n/a
Thanks Ben! Frankly, I was not even familiar with Connect before this
issue come up. I always open bugs with MSFT by calling Dev. support
and shelling out $250 ( then they refund it eventually ). Obviously,
this enthusiasm could go only so far...:) We'll see if this could get
escalated.
On Sep 28, 11:23 am, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
"vcquestions" <vcquesti...@gmail.comwrote in message

news:11**********************@57g2000hsv.googlegro ups.com...


On Sep 14, 1:21 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
Thanks in advance!
vcq- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -
Thanks Ben! On the iteration ( 1-st question ) do you see a clean
workaround ( a different method of iterating through collection &
updating values )?
Also, thanks for pointing out the KeyValuePair issue!
As I said, I think it is a bug in the BCL Dictionary<TKey,TValue>::Insert
helper function. There are two code paths, one for when the key already
exists, and one where it does not. The first of those should not
increment
the private version variable which effectively kills all existing
enumerators.
If you submit a bug on Connect, post the link here. I will validate it
and
vote for it.
I got the bug part - I just refused to believe that MSFT gives us such
pleasant surprises -:) ( but after Debug::Assert( 0 ) showing up in
release mode - oh well... )
here's the link:
https://connect.microsoft.com/Visual...wFeedback.aspx...

They appear to be hiding behind "It's not wrong, because we choose to define
the correct behavior as the way it works". I've added a bunch of counter
examples -- in C++/CLI -- to the bug report in the hope that somebody
realizes that there's value in having .NET collections act the same way
every other collection in the world does.- Hide quoted text -

- Show quoted text -

Sep 29 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.