使用LINQ在一行中对一维实例应用操作

时间:2010-09-01 11:19:50

标签: linq generics

考虑以下结构:

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; }
}

我需要操作20个左右的 Property 实例。我想尽可能干净地做到这一点......是否可以在一行代码中对 Property 数组应用多个操作?

我正在考虑以下几点:

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

3 个答案:

答案 0 :(得分:1)

如果您使用Each代表编写了自己的Action<T>方法,则可以。

修改

实际上它不起作用。您正在使用值类型。有什么理由不能成为class

DimensionProperty都必须是该分配的引用类型,以便在处理列表后反映出来。

答案 1 :(得分:1)

您可以编写Each扩展方法,但由于您的对象是结构体,因此无法使其在IEnumerable<T>上运行。但是,您可以使用带有ref参数的委托来创建一个适用于数组的扩展方法:

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);

然而,由于Dimension也是一个结构,它不会以这种方式工作(并且编译器会检测它并给你一个错误)。你必须做这样的事情:

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

总的来说,如果你的类型是类而不是结构,那么一切都会很多更简单......

答案 2 :(得分:0)

我最终这样做了:

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


注意:我已将结构转换为类。如果我采用原始的基于结构的设计;我不得不“新建”结构以改变它们的价值。像这样:

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