One unfortunate limitation of .net languages is that they don't have any concept of a property doing anything other than returning a value, which can then be used however the caller sees fit. It would be very helpful (and if I had a means of petitioning for language features, I'd seek this) if there were a standard compiler-supported means of exposing properties as delegate callers, such that a statement like:
MyListOfPoints[4].X = 5;
could be translated by the compiler into something like:
MyListOfPoints.ActOnItem(4, (ref Point it) => it.X = 5);
Such code could be relatively efficient, and not create any GC pressure, if ActOnItem
took an extra ref parameter of generic type, and passed it to a delegate which also took a parameter of that type. Doing that would allow the called function to be static, eliminating the need to create a closures or delegates for each execution of the enclosing function. If there were a way for ActOnItem
to accept a variable number of generic 'ref' parameters, it would even be possible to handle constructs like:
SwapItems(ref MyListOfPoints[4].X, ref MyListofPoints[4].Y);
with arbitrary combinations of 'ref' parameters, but even just having the ability to handle the cases where the property was "involved in" the left of an assignment, or a function was called with a single property-ish 'ref' parameter, would be helpful.
Note that being able to do things this way would offer an extra benefit beyond the ability to access fields of structs. It would also mean that the object exposing the property would receive notification that the consumer was done with it (since the consumer's delegate would return). Imagine, for example, that one has a control that shows a list of items, each with a string and a color, and one wants to be able to do something like:
MyControl.Items(5).Color = Color.Red;
An easy statement to read, and the most natural-reading way to change the color of the fifth list item, but trying to make such a statement work would require that the object returned by Items(5)
have a link to MyControl
, and send it some sort of notification when it changed. Rather complicated. By contrast, if the style of call-through indicated above were supported, such a thing would be much simpler. The ActOnItem(index, proc, param)
method would know that once proc
had returned, it would have to redraw the item specified by index
. Of some importance, if Items(5)
were a call-through proc and didn't support any direct read method, one could avoid scenarios like:
var evil = MyControl.Items(5);
MyControl.items.DeleteAt(0);
// Should the following statement affect the item that used to be fifth,
// or the one that's fifth now, or should it throw an exception? How
// should such semantics be ensured?
evil.Color = Color.Purple;
The value of MyControl.Items(5)
would remain bound to MyControl
only for the duration of the call-through involving it. After that, it would simply be a detached value.
not possible to do lists[0]._x=5
: I think you should post the code. At the very least your struct – Bolometerobject
sense; more in theref MyStruct
sense. – Edlun