Reputation: 2852
I have lists of two Shapes - Rectangles and Circles. They both share 3 common properties - ID , Type and Bounds
Circles have 2 extra properties - Range and Center
How can i join lists of each type into a single list so i can iterate over them so i don't have to type two foreach cycles
Could this be donne in a better way than combining the lists ?
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; }
}
Upvotes: 1
Views: 549
Reputation: 35716
How about this
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 }));
it gives a list of enumerable of an anonymous type that exposes the required information.
EDIT
To my amazement this actually seems to compile. So there is a solution that works without defining a common interface. However for anything but the quick and dirty I would consider polymorphic over anonymous.
Upvotes: 1
Reputation: 8511
You could make them each use an IShape interface, or you could iterate over Objects and cast.
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
}
There is also the Zip function that will allow you to enumerate over all of them.
An example:
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);
}
Upvotes: 2
Reputation: 499002
Make both IRectangle
and ICircle
inherit from a shared type - say IShape
.
A List<IShape>
will then be able to take any IRectangle
and ICircle
types and their inheriting types.
Since both IRectangle
and ICircle
share a number of properties, you can do this:
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
{
}
Upvotes: 6
Reputation: 41549
Make an interface IShape
that contains the common properties, then implement that as well as ICircle and IRectangle. (You could also use a base class that has the properties).
You should them be able to join list of Circles and Rectangles to get a list of IShapes.
Upvotes: 5
Reputation: 7412
You could further add an interface
public interface IShape
{
string Id;
GeoLocationTypes Type;
Bounds Bounds;
}
Upvotes: 3