I'm a C++ expert, but not at all for C#. I created a Dictionary<string, STATS>
, where STATS
is a simple struct
. Once I built the dictionary with initial string
and STATS
pairs, I want to modify the dictionary's STATS
value. In C++, it's very clear:
Dictionary<string, STATS*> benchmarks;
Initialize it...
STATS* stats = benchmarks[item.Key];
// Touch stats directly
However, I tried like this in C#:
Dictionary<string, STATS> benchmarks = new Dictionary<string, STATS>();
// Initialize benchmarks with a bunch of STATS
foreach (var item in _data)
benchmarks.Add(item.app_name, item);
foreach (KeyValuePair<string, STATS> item in benchmarks)
{
// I want to modify STATS value inside of benchmarks dictionary.
STATS stat_item = benchmarks[item.Key];
ParseOutputFile("foo", ref stat_item);
// But, not modified in benchmarks... stat_item is just a copy.
}
This is a really novice problem, but wasn't easy to find an answer.
EDIT: I also tried like the following:
STATS stat_item = benchmarks[item.Key];
ParseOutputFile(file_name, ref stat_item);
benchmarks[item.Key] = stat_item;
However, I got the exception since such action invalidates Dictionary:
Unhandled Exception: System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
at helper.Program.Main(String[] args) in D:\dev\\helper\Program.cs:line 75
The only difference is that you cannot modify string literals, whereas you can modify arrays. Functions that take a C-style string will be just as happy to accept string literals unless they modify the string (in which case your program will crash).
In computer science, self-modifying code (SMC) is code that alters its own instructions while it is executing – usually to reduce the instruction path length and improve performance or simply to reduce otherwise repetitively similar code, thus simplifying maintenance.
Self-modifying programs are programs which are able to modify their own code at runtime. Nowadays, self- modifying programs are commonly used. For example, a packer transforms any program into a program with equiva- lent behavior, but which decompresses and/or decrypts some instructions.
A pointer may be a special memory location that's capable of holding the address of another memory cell. So a personality pointer may be a pointer that will point to any location holding character only. Character array is employed to store characters in Contiguous Memory Location.
If your STATS
is indeed a struct
, that means it's a value type, so where you do this:
STATS stat_item = benchmarks[item.Key];
ParseOutputFile("foo", ref stat_item);
Your stat_item
is a copy of the value located at benchmarks[item.Key]
. Thus when you pass it as a ref
parameter to ParseOutputFile
, only the copy is modified.
In the C++ code you posted, notice you would do what you're trying to accomplish here by using a pointer.
For .NET, the solution is simple: change STATS
to a reference type (a class
rather than struct
). Then your local stat_item
variable will be a reference to the same object referenced by the value of benchmarks[item.Key]
.
You should just change STATS to a class. Then you wouldn't need the ref keyword and the object would change.
The usual advice in C# is to use classes unless you are absolutely certain you need a struct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With