Related Post: C# interface method ambiguity
Code from the same source:
private interface IBase1
{
int Percentage { get; set; }
}
private interface IBase2
{
int Percentage { get; set; }
}
private interface IAllYourBase : IBase1, IBase2
{
}
private class AllYourBase : IAllYourBase
{
private int _percentage;
public int Percentage
{
get { return _percentage; }
set { _percentage = value; }
}
}
private void Foo()
{
IAllYourBase iayb = new AllYourBase();
int percentage = iayb.Percentage; // Fails to compile. Ambiguity between 'Percentage' property.
}
(But does not answer my question — “WHY the contracts become ambiguous? ” )
Given:
Interface is a contract that the implementing class MUST abide with.
If two (or more) interfaces ask for the same contract and a interface passes them ‘forward’ and then class implements both of them and ACCEPTS that the common contracts should serve as just one contract for the implementing classes (by not providing an explicit implementation). Then,
-
Why does compiler shows ‘ambiguity’ warning over the common contracts?
-
Why the compiler fails to compile on trying to access the ambiguous contract through interface( iayb.Percentage) ?
I would like to know what benefit compiler is serving with this restriction?
Edit: Providing a real world use case where I would like to use contracts across interfaces as one contract.
public interface IIndexPriceTable{
int TradeId{get;}
int IndexId{get;}
double Price{get;}
}
public interface ILegPositionTable{
int TradeId {get;}
int LegId {get;}
int Position {get;}
}
public interface ITradeTable {
int TradeId{get;}
int IndexId{get;}
int LegId{get;}
//others
}
public interface IJoinedTableRecord : IIndexPriceTable, ILegPositionTable, ITradeTable {
//Just to put all contracts under one interface and use it as one concrete record, having all information across different tables.
}
- Why would I like to have 3-TradeId, 2-LegId, 2-IndexId in my joined table record?
Because the interface
IAllYourBasedoes not declare thePercentageproperty itself.When you assign an instance of
AllYourBaseto a variable ofIAllYourBasethe compiler needs to output a call to eitherIBase1.PercentageorIBase2.Percentage:or
These are different members on different types and just because they have the same signature doesn’t mean they are interchangeable.
In your real world situation you might need finer grained interfaces that define the common properties.