C#组合了两组不同的列表进行迭代

时间:2012-07-13 16:13:29

标签: c# linq list

我有两个形状列表 - 矩形和圆形。 它们共享3个共同属性 - ID,类型和边界

圈子有2个额外的属性 - 范围和中心

如何将每种类型的列表加入到单个列表中,以便我可以迭代它们,这样我就不必键入两个foreach循环

这可能比组合列表更好吗?

public interface IRectangle
{
    string Id { get; set; }
    GeoLocationTypes Type { get; set; }
    Bounds Bounds { get; set; }
}

public class Rectangle : IRectangle
{
    public string Id { get; set; }

    public GeoLocationTypes Type { get; set; }

    public Bounds Bounds { get; set; }
}


public interface ICircle
{
    string Id { get; set; }
    GeoLocationTypes Type { get; set; }
    Bounds Bounds { get; set; }
    float Radius { get; set; }
    Coordinates Center { get; set; }
}

public class Circle : ICircle
{
    public string Id { get; set; }

    public GeoLocationTypes Type { get; set; }


    public Bounds Bounds { get; set; }

    public float Radius { get; set; }

    public Coordinates Center { get; set; }
}

public class Bounds
{
    public Coordinates NE { get; set; }

    public Coordinates SW { get; set; }
}

public class Coordinates
{
    public float Lat { get; set; }

    public float Lng { get; set; }
}

5 个答案:

答案 0 :(得分:6)

IRectangleICircle继承共享类型 - 比如IShape

然后List<IShape>可以使用任何IRectangleICircle类型及其继承类型。

由于IRectangleICircle共享许多属性,您可以这样做:

public interface IShape
{
    string Id { get; set; }
    GeoLocationTypes Type { get; set; }
    Bounds Bounds { get; set; }
}

public interface ICircle : IShape
{
    float Radius { get; set; }
    Coordinates Center { get; set; }
}

public interface IRectangle : IShape
{
}

答案 1 :(得分:5)

创建一个包含公共属性的接口IShape,然后实现它以及ICircle和IRectangle。 (您也可以使用具有属性的基类。)

您应该能够加入圆圈和矩形列表以获取IShapes列表。

答案 2 :(得分:3)

您可以进一步添加界面

public interface IShape
{
    string Id;
    GeoLocationTypes Type;
    Bounds Bounds;
}

答案 3 :(得分:2)

你可以让它们各自使用一个IShape接口,或者你可以迭代对象和强制转换。

public interface IShape
{
    string Id { get; set; }
    GeoLocationTypes Type { get; set; }
    Bounds Bounds { get; set; }
}

public interface IRectangle : IShape { }

public class Rectangle : IRectangle
{
    // No change
}


public interface ICircle : IShape
{
    float Radius { get; set; }
    Coordinates Center { get; set; }
}

public class Circle : ICircle
{
    // No change
}

public class Bounds
{
    // No change
}

public class Coordinates
{
    // No change
}

还有Zip功能可以让你枚举所有这些功能。

一个例子:

var numbers= new [] { 1, 2, 3, 4 };
var words = new [] { "one", "two", "three" };

var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w });
foreach(var nw in numbersAndWords)
{
    Console.WriteLine(nw.Number + nw.Word);
}

答案 4 :(得分:1)

这个怎么样

var merged = Rectagles.Select(r => new { 
        r.Id, 
        r.Type, 
        r.Bounds,
        Radius = float.NaN,
        Centre = default(Coordinates) })
    .Concat(Circles.Select(c => new {
        c.Id, 
        c.Type, 
        c.Bounds,
        c.Radius,
        c.Centre }));

它给出了一个匿名类型的可枚举列表,它公开了所需的信息。


修改

令我惊讶的是,这实际上似乎在编译。因此,有一种解决方案无需定义通用接口即可运行。但是对于除了快速和肮脏之外的任何事情,我都会考虑使用多态而不是匿名。