Consider the following example:
interface IBase1
{
int Percentage { get; set; }
}
interface IBase2
{
int Percentage { get; set; }
}
interface IAllYourBase : IBase1, IBase2
{
}
class AllYourBase : IAllYourBase
{
int percentage;
int Percentage {
get { return percentage; }
set { percentage = value; }
}
}
void Foo()
{
IAllYourBase iayb = new AllYourBase();
int percentage = iayb.Percentage; // Fails to compile. Ambiguity between 'Percentage' property.
}
In the example above, there is ambiguity between which Percentage
property to call. Assuming the IBase1
and IBase2
interfaces may not be changed, how would I go about resolving this ambiguity in the cleanest, most preferred way?
Based on the responses I was getting for using explicit interface implementation, I want to mention that while this does solve the problem it does not solve it in an ideal way for me because I use my AllYourBase
object as an IAllYourBase
most of the time, never as an IBase1
or IBase2
. This is mostly because IAllYourBase
also has interface methods (I failed to detail those in my code snippet above because I thought they were irrelevant) that are implemented by AllYourBase
and I want to access those too. Casting back and forth all the time will get very tedious and result in messy code.
I did try one solution that involved defining the Percentage
property in IAllYourBase
and not using explicit interface implementation, which seemed to get rid of the compiler error at least:
class IAllYourBase : IBase1, IBase2
{
int Percentage { get; set; }
}
Is this a valid solution?
Implement explicitly:
public class AllYourBase : IBase1, IBase2
{
int IBase1.Percentage { get{ return 12; } }
int IBase2.Percentage { get{ return 34; } }
}
If you do this, you can of course treat your non-ambigous properties just like normal.
IAllYourBase ab = new AllYourBase();
ab.SomeValue = 1234;
However, if you want to access the percentage prop this will not work (Suppose it did, which value would be expected in return?)
int percent = ab.Percentage; // Will not work.
you need to specify which percentage to return. And this is done by casting to the correct interface:
int b1Percent = ((IBase1)ab).Percentage;
As you say, you can redefine the properties in the interface:
interface IAllYourBase : IBase1, IBase2
{
int B1Percentage{ get; }
int B2Percentage{ get; }
}
class AllYourBase : IAllYourBase
{
public int B1Percentage{ get{ return 12; } }
public int B2Percentage{ get{ return 34; } }
IBase1.Percentage { get { return B1Percentage; } }
IBase2.Percentage { get { return B2Percentage; } }
}
Now you have resolved the ambiguity by distinct names instead.