views:

36

answers:

4

Consider this example:

public interface IAccount
{
    string GetAccountName(string id);
}

public class BasicAccount : IAccount
{
    public string GetAccountName(string id)
    {
        throw new NotImplementedException();
    }

}

public class PremiumAccount : IAccount
{
    public string GetAccountName(string id)
    {
        throw new NotImplementedException();
    }

    public string GetAccountName(string id, string name)
    {
        throw new NotImplementedException();
    }
}

protected void Page_Load(object sender, EventArgs e)
{

    IAccount a = new PremiumAccount();

    a.GetAccountName("X1234", "John"); //Error
}

How can I call the overridden method from the client without having to define a new method signature on the abstract/interface (since it is only an special case for the premium account)? I'm using abstract factory pattern in this design... thanks...

+2  A: 

You will have to cast the interface to the specific class. Keep in mind that this would throw the whole concept of interfaces right out of the window and you could be using specific classes in all cases. Think about adjusting your architecture instead.

Femaref
yes, as I said, it's only for special cases, since abstract pattern has no specific solution for special cases like this...
CSharpNoob
+1  A: 

Well, considering it's only defined for the PremiumAccount type, the only way you know you can call it is if a is actually a PremiumAccount, right? So cast to a PremiumAccount first:

IAccount a = new PremiumAccount();

PremiumAccount pa = a as PremiumAccount;
if (pa != null)
{
    pa.GetAccountName("X1234", "John");
}
else
{
    // You decide what to do here.
}
Dan Tao
+2  A: 

You cast the reference to the specific type:

((PremiumAccount)a).GetAccountName("X1234", "John");
Guffa
` IAccount a = new PremiumAccount();` so there is no need to cast
SaeedAlg
@SaeedAlg: You are mistaken. The reference is of the type `IAccount`, so it doesn't know about the methods that only exist in `PremiumAccount`.
Guffa
sorry method names was same :D
SaeedAlg
+2  A: 

You can define IPremiumAccount interface with both methods and implement it the PremiumAccount class. Checking if an object implements the interface is probably better than checking for specific base class.

public interface IPremiumAccount : IAccount
{
    public string GetAccountName(string id, string name);
}

public class PremiumAccount : IPremiumAccount
{

// ...

IAccount a = factory.GetAccount();
IPremiumAccount pa = a as IPremiumAccount;
if (pa != null)
    pa.GetAccountName("X1234", "John");
Athari