Reputation: 73
I am dealing with two interfaces:
public interface ICoordinates
{
double Latitude { get; set; }
double Longitude { get; set; }
}
and
public interface ILocation
{
ICoordinates Coordinate1 { get; set; }
ICoordinates Coordinate2 { get; set; }
}
Implementing them so:
class Coordinates : ICoordinates
{
public double Latitude {get; set;}
public double Longitude {get; set;}
public Coordinates(double p1, double p2)
{
this.Latitude = p1;
this.Longitude = p2;
}
}
class Location : ILocation
{
public Coordinates Coordinate1 { get; set; }
public Coordinates Coordinate2 { get; set; }
public Location(Coordinates c1, Coordinates c2)
{
this.Coordinate1 = c1;
this.Coordinate2 = c2;
}
}
However this gives me a compiler error.
1>C:\Users\Administrator\Documents\Visual Studio 2012\Projects\Twitter_twitinvi\Twitter_twitinvi\Program.cs(36,11,36,19): error CS0738: 'Twitter_twitinvi.Location' does not implement interface member 'Tweetinvi.Core.Interfaces.Models.ILocation.Coordinate2'. 'Twitter_twitinvi.Location.Coordinate2' cannot implement 'Tweetinvi.Core.Interfaces.Models.ILocation.Coordinate2' because it does not have the matching return type of 'Tweetinvi.Core.Interfaces.Models.ICoordinates'.
Can't understand what I m doing wrong here. As class Coordinates does inherit from ICoordinates. So what does this error mean?
Thanks
Upvotes: 1
Views: 124
Reputation: 84815
You already got a good answer explaining that the signatures of the Coordinates1
and Coordinates2
properties in your implementing class (Location
) must exactly match the signatures as they are defined in the interface ILocation
.
You might ask why that is so. Let's consider that someone other than you might create an alternate implementation of the ICoordinates
interface:
class Coordinates : ICoordinates { /* your implementation */ }
class FooCoordinates : ICoordinates { /* an alternative implementation */ }
Now, let's say we have a reference to an ILocation
object. As per the interface definition, we can set the Coordinates1
and Coordinates2
properties to any object that implements ICoordinates
. That is, the following would work:
ILocation location = …;
location.Coordinates1 = new Coordinates();
location.Coordinates2 = new FooCoordinates();
Now let's consider your implementation of ILocation
. You want to declare your properties to have the type Coordinates
instead of ICoordinates
(as the interface mandates). If the resulting properties were a legal implementation for ILocation.Coordinates[1|2]
, then the following would be possible:
Location location = new Location();
ILocation locationAsSeenThroughTheInterface = location;
locationAsSeenThroughTheInterface.Coordinates2 = new FooCoordinates();
Coordinates coordinates2 = location.Coordinates2;
That is, you could set Coordinates2
to a FooCoordinates
object by first casting location
to the interface type that it supports; then you would read the same property back directly through location
(without a cast). According to the declared types, you'd expect to get back a Coordinates
object when the property was set to a FooCoordinates
object.
Or, in different words: The last two lines of code are problematic. The penultimate line of code would set a property of type Coordinates
to a FooCoordinates
object, which should of course be forbidden... but the type system would have no way of knowing. The last line of code would read a FooCoordinates
object out of a Coordinates
-types property, which should be equally impossible.
There is only one way to prevent these ugly type mismatches: You are required to implement the interface exactly as you've defined it; including the precise return types.
Upvotes: 1
Reputation: 24916
In your location class you need to use properties of type ICoordinates
, not Coordinates
:
class Location : ILocation
{
public ICoordinates Coordinate1 { get; set; }
public ICoordinates Coordinate2 { get; set; }
public Location(ICoordinates c1, ICoordinates c2)
{
this.Coordinate1 = c1;
this.Coordinate2 = c2;
}
}
When you have an interface you need to implement it just as it is, including return types. Even though class Coordinates
implements ICoordinates
you still need to use exact signature, you cannot change it.
Upvotes: 3