Changing the value of an element in a list of structs
MyList[1] = new MyStruct("bob");
structs in C# should almost always be designed to be immutable (that is, have no way to change their internal state once they have been created).
In your case, what you want to do is to replace the entire struct in specified array index, not to try to change just a single property or field.
Changing the value of an element in a struct
For starters the order of evaluation of arguments in a function call is unspecified.
So in this call
printf("%d %d\n",strleng(A),A.length);
the evaluation of the argument expression A.length
can occur before calling the function strleng
or vice versa.
Secondly the function strleng
declared like
int strleng(stru A);
deals with a copy of the original object A
declared in main and used as an argument. So changing the copy does not influence on the original object.
You need to pass the object by reference through a pointer to it.
unsigned int strleng( stru *A){
unsigned int i=0;
while(A->string[i]!='\0'){
i++;
}
A->length =i;
return i;
}
and in main you should write for example
unsigned int n = strleng( &A );
printf("%u %u\n", n, A.length );
Pay attention to that on one hand, the data member length
is declared as having the type unsigned int
unsigned int length;
On the other hand, within your original function strleng
you are using an object of the signed type int
and the function return type is also int
. The function should use at least the same type unsigned int
instead of the type int
.
c# modifying structs in a List T
Looking at the for-loop approach, the reason (and solution) for this is given in the documentation for the compilation error:
An attempt was made to modify a value
type that is produced as the result of
an intermediate expression but is not
stored in a variable. This error can
occur when you attempt to directly
modify a struct in a generic
collection.To modify the struct, first assign it
to a local variable, modify the
variable, then assign the variable
back to the item in the collection.
So, in your for-loop, change the following lines:
catSlots[s].subItems.Clear();
catSlots[s].subItems = sortedSubTemp; // ERROR: see below
...into:
slotInfo tempSlot = gAllCats[0].items[s];
tempSlot.subItems = sortedSubTemp;
gAllCats[0].items[s] = tempSlot;
I removed the call to the Clear
method, since I don't think it adds anything.
How to update variable in single element of struct list
This is a perfect example why using mutable strcuts is pure evil. Basically whenever your values might change you should consider to use a class instead of struct.
As of MSDN:
X DO NOT define mutable value types
The problem you got arises from the fact that structs are value-types which get copied whenever passed to or returned from a member - in your case List.Find
. Thus any updates to the instance you recieved via Find
won´t be reflected to the instance within the list. You could strangly bypass this by using an array instead of a list, but that´s also a bad idea as it hides the actual problem.
How can I change the element in an array of struct
Pair
is a struct, so value semantics apply. This means that here, you made a copy of each item in data.pairs
:
var pair = data?.pairs[index]
And you are changing the copies, not the originals.
One way to solve this is to assign the changed copies back to data.pairs
:
if /* some test */ {
print ("Found match")
pair?.setValue(Point(1,2))
data?.pairs[index] = pair // here!
}
Or, don't make a copy in the first place:
if /* some test */ {
print ("Found match")
data?.pairs[index].setValue(Point(1,2))
}
Or, make Pair
a class, so reference semantics apply, and you won't be making copies.
Search for and replace a value in a vector of structs
To change the elements in the vector, you need to take a reference in the range-for loop:
for (auto &e : data)
Otherwise you are making a copy, which doesn't change the original elements.
The 4th parameter of replace_if
needs to take an info
object, not just the new_name
value.
Instead of replace_if
, the appropriate algorithm to use here would be for_each
, which modifies the info
objects as needed:
std::for_each(data.begin(), data.end(),
[old_name, new_name](info &i) {
if (i.name == old_name)
i.name = new_name;
});
However, in this case, the range-for loop is probably less code, and easier to read and write.
Also, please avoid using namespace std;
, it's bad practice.
Related Topics
How to Send Emails Through Ssl Smtp with the .Net Framework
At the End of an Async Method, Should I Return or Await
What Is the Purpose of Self Tracking Entities
How to Serialize/Deserialize to 'Dictionary<Int, String>' from Custom Xml Not Using Xelement
How to Set a Property Value with Reflection
Xaml Binding Not Working on Dependency Property
How to Ignore JSONproperty(Propertyname = "Somename") When Serializing JSON
Format Excel Column to Decimal Doing Export from C#
What Is [Serializable] and When Should I Use It
Using Linq to Concatenate Strings
Convert String to Datetime in C#
C# Class to Parse Webrequestmethods.Ftp.Listdirectorydetails Ftp Response
Why Does This Floating-Point Calculation Give Different Results on Different MAChines