2012-07-13 61 views
1

我有兩個形狀 - 矩形和圓形的列表。 他們都分享3共同的特性 - ID,類型和邊界C#將兩組不同的列表組合在一起

圈有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; } 
} 
+0

我會推薦先將Circle和Rectangle轉換成一個'IShape'(它們來自該接口)。正如你現在所看到的,Circle和Rectangles沒有共同之處。 – 2012-07-13 16:18:46

+0

定義「更好」。更高效?更容易維護/閱讀?他們在單獨的名單中是否有原因?你可以讓你的不同形狀從更抽象的對象類型下降,並使用<你的抽象類型>的列表,但是如果你需要引用,那麼當迭代更通用的列表時,你必須將對象轉換爲正確的特定子類他們的具體屬性。名單 ...包含長頸鹿,土狼,斑馬等 – Tim 2012-07-13 16:21:50

回答

6

使IRectangleICircle都從共享類型繼承 - 比如說IShape

A 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 
{ 
} 
+0

洛爾 - 偉大的思想和一切! – 2012-07-13 16:17:17

+2

@JonEgerton - 是的,儘管問題和OOP繼承文獻,幾乎保證了這種反應;) – Oded 2012-07-13 16:17:55

+0

問:當我去irerate名單是我看到的IShape的唯一屬性,如何訪問IRectangle時的那些會發生什麼我打了一個迭代? – Aviatrix 2012-07-14 13:45:40

3

你可以進一步增加一個接口

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

使包含公共屬性的接口IShape,然後實現以及ICircle和IRectangle。 (你也可以使用具有屬性的基類)。

你應該能夠連接圓形和矩形列表來獲得一個IShapes列表。

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

它給人的枚舉暴露所需信息的匿名類型的列表。


編輯

令我驚訝這實際上似乎編譯。所以有一個解決方案可以在不定義通用接口的情況下工作。然而,除了快速和骯髒之外,我會考慮匿名的多態。

相關問題