IRefEnumerable support to foreach and array #2503
Replies: 24 comments
-
How would And is the goal to allow writing to the collection inside var array = new int[10];
foreach (ref int i in array)
{
i = -1;
} |
Beta Was this translation helpful? Give feedback.
-
@svick Yes, I wish it would work like that. And it would be used to manipulate collection of large struct like matrix. But well, writing collection like that in foreach would be neat too I wish compiler for Not sure we could use var array = new int[10];
foreach (ref var i in array)
i = -1;
foreach (var i in array) // possible?
i = -1; |
Beta Was this translation helpful? Give feedback.
-
That's not in line with how it works now. The compiler first looks for a |
Beta Was this translation helpful? Give feedback.
-
Oh yes, that's right. We actually need public interface IRefEnumerable<T>
{
IRefEnumerator<T> GetEnumerator()
}
public interface IRefEnumerator<T>
{
ref T Current { get; }
bool MoveNext { get; }
} |
Beta Was this translation helpful? Give feedback.
-
AFAIK, for arrays, |
Beta Was this translation helpful? Give feedback.
-
@alrz Right, arrays (and |
Beta Was this translation helpful? Give feedback.
-
@Thaina I still think you can't reuse the
Consider public class List<T> : IEnumerable<T>
{
public struct Enumerator : IEnumerator<T>
{
List<T> list;
int index;
internal Enumerator(List<T> list) { … }
public T Current => list[index];
…
}
public Enumerator GetEnumerator() => new Enumerator(this);
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this);
} With the public class List<T> : IRefEnumerable<T>
{
public struct RefEnumerator : IRefEnumerator<T>
{
List<T> list;
int index;
internal Enumerator(List<T> list) { … }
// assuming ref T Get() on List<T>
public ref T Current => ref list.Get(index);
…
}
public RefEnumerator GetRefEnumerator() => new RefEnumerator(this);
IRefEnumerator<T> IRefEnumerable<T>.GetRefEnumerator() => new RefEnumerator(this);
} I don't think you could do the same if the method was named |
Beta Was this translation helpful? Give feedback.
-
Well, that's right. So I think we need to extend |
Beta Was this translation helpful? Give feedback.
-
Can you suggest a use-case for these |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Using foreach for collections of Vector2 3 4 up to Matrix4x4 Well, if you never handle large struct with bulk operation you would never understand |
Beta Was this translation helpful? Give feedback.
-
I get the idea that some folk have the need to process large amounts of data in an effective way and |
Beta Was this translation helpful? Give feedback.
-
@DavidArno for I propose it as interface because we could make any kind of collections for our needed. And the main point I post this issue because for(var i = 0; i < LongNameStructArray.Length; i++)
{
LongNameStructArray[i].Position = Vector3.Zero;
}
// vs
foreach(ref var obj in LongNameStructArray)
{
obj.Position = Vector3.Zero;
} |
Beta Was this translation helpful? Give feedback.
-
Oh I forgot that I should also propose Is it possible for |
Beta Was this translation helpful? Give feedback.
-
You can |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Why you think it must be implied? We always mutate reference type in foreach and it never need to be reenumerated Changing value of a memory block, be it a reference type or ref of value type, is still the same memory block and it never need to reenumerate the same pointer |
Beta Was this translation helpful? Give feedback.
-
What is the point of mutating those elements of the enumeration, if they are never read again? |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Why you think it never be read? After foreach loop that array could be read from anywhere. In game engine there would be tree of matrixes that loop to update each of them in hierarchy and then it will be read by physics / graphics / logic / network / etc / etc / etc / etc / etc As I said, if you never handle large struct with bulk operation you would never understand |
Beta Was this translation helpful? Give feedback.
-
Because you said "We always mutate reference type in foreach and it never need to be reenumerated". But now you are saying that such collections are re-read by "physics / graphics / logic / network / etc / etc / etc / etc / etc". So you are right, I do not understand (still) why you want |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Man, Why you pick the word Really, have you ever mutate array of class in your life? Did you know you can mutate value of class in list when you foreach? Need example? class SomeData { public float x,y,z; }
var datas = new List<SomeData>() { new SomeData(),new SomeData(),new SomeData() };
foreach(var data in datas)
data.x = Random(); See it obviously? Mutation in foreach is such normal things and could be done in any collection. I just want it to extend to collection for struct Now I think you just misunderstand everything. With ref to struct it never change pointer in the array. Each item in array of struct is memory block of it own if you reread it would also be the same pointer And why you are so attached to your |
Beta Was this translation helpful? Give feedback.
-
Collections like |
Beta Was this translation helpful? Give feedback.
-
@HaloFour I know. But with interface we could just implement our own structure ourself and that's what I ask for. I don't ask that we must implement And foreach on ref collection does not move anything. It may change value in the block but it must not move or change the size of the collection while iterate. The array itself would not changed, only the value of each item can change struct Matrix4x4 {}
SomeRefCollections<Matrix4x4> ms;
foreach(ref var m in ms)
m.Position = Vector3.Zero;
// Changing value of m never change anything of the collection |
Beta Was this translation helpful? Give feedback.
-
With struct Matrix4x4 {}
SomeRefCollections<Matrix4x4> ms;
foreach(ref var m in ms)
m = new Matrix4x4(); But you appear to not want that functionality. It appears that all you want is for a
Is that a correct summary of what you've been asking for here? |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Kinda and yes I think I am fine if you Something like struct Matrix4x4 {}
SomeRefCollections<Matrix4x4> ms;
foreach(ref var m in ms)
m = Matrix4x4.Identity; But it has no reason to not be allowed if we could And yes for 1 and 2 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Follow up from return ref feature. I would like to have
IRefEnumerable<T>
interface included in core C#Which should be implemented natively to array. It should support
foreach
too. And there should be whole set of Linq implementation support ref argumentBut, well, ref linq may be need to ask in corefx (I was once create #7978). But aside from that, native array and foreach support on this feature would require roslyn support I think
Beta Was this translation helpful? Give feedback.
All reactions