tags:

views:

29

answers:

3

Consider the following structures:

internal struct Coordinate
{
    public Double Top { get; set; }
    public Double Left { get; set; }
}

internal struct Dimension
{
    public Double Height { get; set; }
    public Double Width { get; set; }
}

internal struct Property
{
    public Boolean Visible { get; set; }
    internal String Label { get; set; }
    public String Value { get; set; }
    internal Coordinate Position { get; set; }
    public Dimension Dimensions { get; set; }
}

I need to manipulate 20 or so instances of Property. I'd like to do so as cleanly as possible... Is is possible to apply multiple operations on an array of Property in one line of code?

I'm thinking something along the lines of:

new []
{
    InstanceOfProperty,
    InstanceOfProperty,
    InstanceOfProperty ...
}.Each(p => p.Dimensions.Height = 100.0);
+1  A: 

If you wrote your own Each method taking an Action<T> delegate, you could.

Edit:

Actually it wont work. You are using value types. Any reason why it cant be class?

Both Dimension and Property would have to be reference types for that assignment to reflect after processing the list.

leppie
+1  A: 

You can write a Each extension method, but since your objects are structs, you can't make it work on an IEnumerable<T>. However you can make an extension method that works on an array, using a delegate with a ref parameter:

public static class ExtensionMethods
{
    public delegate void RefAction<T>(ref T arg);

    public static void Each<T>(this T[] array, RefAction<T> action)
    {
        for(int i = 0; i < array.Length; i++)
        {
            action(ref array[i]);
        }
    }
}

...

new []
{
    InstanceOfProperty,
    InstanceOfProperty,
    InstanceOfProperty ...
}.Each((ref Property p) => p.Dimensions.Height = 100.0);

However since Dimension is also a struct, it won't work this way (and the compiler will detect it and give you an error). You have to do something like that instead:

new []
{
    InstanceOfProperty,
    InstanceOfProperty,
    InstanceOfProperty ...
}.Each((ref Property p) => p.Dimensions = new Dimension
                           {
                               Width = p.Dimensions.Width,
                               Height = 100.0
                           });

On the whole, everything would be a lot simpler if your types were classes rather than structs...

Thomas Levesque
Looks neat. This was going to be my second "try". Thanks. Could you check my answer to this question and tell me if you foresee any problems?
roosteronacid
A: 

I ended up doing this:

new List<Property> { InstanceOfProperty, InstanceOfProperty, ... }.ForEach((p =>
{
    p.Dimensions.Height = 0.0;
}));


Note: I have converted the structures into classes. If I went with the original struct-based design; I would have had to "new up" the structures in order to change their value. Like so:

new List<Property> { InstanceOfProperty, InstanceOfProperty, ... }.ForEach((p =>
{
    p.Dimensions = new Dimension { Height = 0.0 };
}));
roosteronacid
With classes instead of structures, it should work fine
Thomas Levesque