List<> modification
I want ot modify all elements in a List<>, but im having trouble. This is my code. Which gives an error saying I cannot modify
vertex
because it is a 'foreach iteration variable'
I come from c++, so I can guess that the problem is that var vertex
is copied and not actually what i want to modify. Is there a way to get the actual instance of the vertex in c#?43 Replies
You are adding a new instance of
Vertex
into the List
.
The List
has a length of 1 and can be accessed through a zero-based index -> vertices[0]
.that does not work, it tells me it's not a variable (i assume because it's copying the value)?
In C# most things are referenced, they keyword
ref
is a double-reference. So all classes are referenced by default. Except structs, those are value-types. As you come from cpp you probably know the stack and heap stuff.
vertices
is a variable, scoped within a method, not the program class.one minute, i got an isolated example working, but my actual use-case doesnt work
something like this does not work, but recreating list[0] with a
new Test
does-- is there a way to modify the existing instance without remaking it?
is that what you meant earlier i guess?
since using
fixes itsure, access it through the index
list[0]
.
public float a { get; set; }
is a Property, not a variable and not a field, also this syntax is code-sugar to what it actually is, is way more code, this syntax is called auto-property, since getter and setter are auto generated and the backing/shadow field is also auto-generated.
Properties are class
/object
scoped.i didnt mean to have the
get; set;
, it doesnt actually need to be therepublic float a;
is a fieldim a little confused what the distinction is between property, variable, and field
is it synonymous to like a member variable?
but both are scoped class-wide and can be accessed on other methods, by using the
public
accessor it can also be accessed from outside. This isn't allowed for a field by code convetion, public
should be for properties.
No, big differences - also arguments and parameterswhat would you suggest i use?
the main problem im having is that im using these for vertex data sent to the gpu, and im honestly not knowledgeable enough to know if the layout of a class is acceptable for my shaders
Me neither^^
I don't know which framework you're using, etc.
im on fna, which uses hlsl for its shaders
or actually it's using effects, but same difference i guess
However, if you wanna use the list inside your class and not only inside a single method, then, make it a private field 🙂
private List<Vertex> myVertices;
and put a new instance creation in the ctor, or do it inline like:
private List<Vertex> myVertices = [];
fna? do you mean XNA?fna is like a maintained wrapper on xna since microsoft discontinued xna
and peeps made MonoGame from it, never heard of fna tbh
mostly-- code is just copy-paste away going between the two with some exceptions
yeah, they're all pretty similar
i'd say anything that flies in xna flies in fna most of the time
Okay, I don't know about fna. but for monogame there exists nuget-packages that handles animations, sprites and alike.
im using primitives intentionally since my use is kinda specific and i want to use shaders
anyway, i cant do stuff like this
because it wont let me modify
vertices[0]
and i dont want to create a new one every time since i'll be creating probably thousands or tens of thousands of vertices that will all be modified very oftenIs
Position
readonly?it's written as
public Vector2 Position
How is it defined in
TrailVertex
?the error reads "cannot modify because vertices[0] is not a variable"
TrailVertex
is a struct
there is a CollectionsMarshal.AsSpan(List<T>) helper method which u could use:
because
vertex
is a ref
u directly write to the element in the list, not a copy to itCollectionsMarshal.AsSpan(List) Method (System.Runtime.InteropServi...
Gets a Span view over the data in a list. Items should not be added or removed from the List while the Span is in use.
:/
im on .net 4
oh
On the other hand,
TrailVertex
is a custom object? Why not use a class
instead? Or just Vector2
- structs should be used on small objects only and which represents a single point of data.i simplified the code to not include other data im using per vertex
i can try a class but like i said, im not sure how the layout will affect sending it to the gpu
it seems sketchy since
VertexPositionColor
(an xna written vertex structure) is written as a struct like
VertexPositionColor
implies a single of data, so that's okay.
Dunno what TrailVertex
will do, but if you leave it at Vector2
, struct is fine.
So vertices[0]
complains about not a variable because it's a copy of a value type. Doing something like
honestly i think im just going to use raw arrays since that's copying data anyway
i assume that's how List<T> implements resizing too, so copying once is better than copying twice
since i think vertices[0].Position works on raw arrays
It does work, because there's no layer of a ref-type
Plain array is just not so dynamic as a List or Collection, tho both uses arrays under the hood, but in a more complex way of calculating the initial size of the array etc.
yeah i imagined so
i found a function
Array.Resize<>()
so i think i can make doYay, but that's considered rather low-level in c# and shouldn't be abused, people will tell you to use a
List
instead, unless you really know what you are doing.
Also, as far as I remember, those are like strings, immutable types, so Resize does nothing but copy it to another array.i dont think it's too low level
to me, it seems like i need to know more about the language if i use
List
given the problem we've been talking about this whole timeCompared to other C languages it's way, way, way, more abstract, you cannot really do what real low-level is, like hardware near low-level, that's why cpp is still and will be a thing. The lowest you can go is by using the
unsafe
keyword, which allows you to use unmanaged code.how advised against is
unsafe
since in cpp, im pretty much always writing unsafe
code anyway
i actually thought about fixing this issue by doing something similar to the cs equivalent of
since that way i'd be just getting the pointer to the actual instance i want to modify, but i figured c# isn't meant to be written that wayMostly, unless you know what you are doing and you know how to manage the memory, GC won't hit there and you actually need to use destructors, which in a GC language ain't a thing. So the actual question is, why not use cpp in the first place.
unfortunately, i really cant-- im making a mod for a game that uses fna. I could use dllimports to port c++ into c#, but it's a pain since i need data from the c# side (stuff from the game's memory) that would need to go back and forth between c++ and c#
me and some other guy already made a project that does this, but it's really innefficient since we're basically sending json files between the language and parsing that every frame
mh, sounds like you need some p/invokes and marshalling
maybe, it's hard since i dont know c# well enough to know what works and what doesnt and honestly by the time i do, i think writing c++ code might not even be necessary anymore
also the biggest problem is that fna is written to support opengl, vulkan, and direct3d, but only uses hlsl for shaders, meaning in c++, i'd have to implement all 3 and build my own shader transpiler
you could write cpp dlls and via marshalling get the data from unmanaged back to actually managed code to make use of c#.
okay, I see the problem here, kinda challanging, also by being bound to the old .net framework.
are you experienced doing things like that?
the current project we wrote used c++ with imgui and imgui works by taking in a pointer to what data you want in the ui, then updates the value at the pointer depending on user input-- meaning you dont have to copy a bunch of stuff and i want to write an imgui wrapper so we can move all the logic to c# while not having to copy data
No, I did stuff, but definitely not experienced enough, but people at #allow-unsafe-blocks will help you, they are the cracks here.
alright, ill explore a bit and see what i can do