Long story short, I'll provide a simplistic example where it might be useful:
public struct Vector3f {
public float x;
public float y;
public float z;
public unsafe float this[int index] {
get {
// Get "p" somehow, so that it points to "this"...
return p[index];
}
set {
// Get "p" somehow, so that it points to "this"...
p[index] = value;
}
}
}
I guess you got my point there:
var v = new Vector3f();
Assert(v.x == v[0]);
EDIT 1:
For those, who still ask :)
Assert(v.y == v[1]);
Assert(v.z == v[2]);
EDIT 2:
Does fixed
create redundant overhead here?
Or maybe this struct is already fixed, and therefore fixed
has no effect here and is only needed to satisfy the compiler? Possible answer.
First off, I would not use unsafe code for this unless I had first determined (1) that the obvious code with the switch would be the slowest code in the entire program and causing significant, user-observable slowdowns, and that (2) going to unsafe code fixes the performance problem.
Second, if I were to use unsafe code, it is extraordinarily dangerous to make assumptions about structure packing. The CLR is allowed broad lattitude in how it chooses to pack structures. If you are going to do this dangerous thing then you should use the struct layout attribute to ensure that the floats are exactly where you need them to be.
Third, what stops a buggy caller from passing a negative index, or a too-large index?
Fourth:
Does fixed create redundant overhead here?
I don't know what "redundant overhead" means. "fixed" makes the jitter tell the garbage collector "do not move this thing because I need to do pointer arithmetic on it". You are fixing for a short period, which is ideal; fixing for a long time makes it more likely that a collection will get messed up because the pinned storage could not be moved.
Fifth:
Or maybe this struct is already fixed, and therefore fixed has no effect here and is only needed to satisfy the compiler?
Maybe! Maybe the variable referred to by "this" is already a fixed variable. Maybe it isn't. How is the compiler supposed to know whether the "this" of the struct is a ref to fixed storage or not? We have to assume the worst, so you are required to fix it.
You mean something like this?
get
{
// (index validation omitted)
fixed (Vector3f* thisPtr = &this)
{
return ((float*)thisPtr)[index];
}
}
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