Search code examples
c#asp.netoopaccess-modifiers

How access to abstract property from abstract that inherits interface?


I am not able to access a virtual property (IsNameAPalindrome) of an abstract class (PetBase ) having interface(IPet) inherited.

public interface IPet
{
    string Name { get; set; }
}

public abstract class PetBase : IPet
{
    public abstract string Name { get; set; }

    public virtual bool IsNameAPalindrome
    {
        get
        {
            return (Name.Equals(string.Join("", Name.Reverse())));
        }
    }

}

The derived classes inherit the abstract class (PetBase)

public class Bird : PetBase
{
    public override string Name { get; set; }
}

public class Cat : PetBase
{
    public override string Name { get; set; }

}

public class Dog : PetBase
{
    public override string Name { get; set; }
}

public class House : List<IPet>
{        
}

Now when I try to access the property(IsNameAPalindrome) while looping through house object, it is not accessible

 class Program
{
    static void Main(string[] args)
    {
        House house = BuildHouse();
        Print(house);
    }


    static void Print(House house)
    {
        // TODO: Print the contents of the house similar to the below.
        // Feel free to change or improve upon the table as you see fit.

        //Name    Palindrome
        //Gracie  False     
        //Patches False     
        //Izzi    True      
        //Missy   False     
        
        Console.WriteLine("Name Palindrome");
        foreach (var item in house)
        {
            Console.WriteLine( item.Name);

        }
    }

    static House BuildHouse()
    {
        House house = new House();

        house.Add(new Cat()
        {
            Name = "Gracie"
        });

        house.Add(new Cat()
        {
            Name = "Patches"
        });

        house.Add(new Bird()
        {
            Name = "Izzi"
        });

        house.Add(new Dog()
        {
            Name = "Missy"
        });

        return house;
    }
}

Solution

  • You define House as List<IPet>, meaning the compiler will see each list element as the type IPet, which does not have a property IsNameAPalindrome.

    If it makes logical sense for IsNameAPalindrome to be part of that interface contract, the simple solution is to add it:

    public interface IPet
    {
        string Name { get; set; }
        bool IsNameAPalindrome { get; }
    }
    

    If that does not make sense to you (and it may not, given that palendromes aren't closely linked to the concept of being a pet), you can:

    • Cast each IPet to PetBase to access that property
    • Implement a new interface e.g. IPalendrome, have PetBase also implement that interface, and cast to that interface to access the method.

    Changes to the code for

    First option

    Console.WriteLine( ((PetBase)item).IsNameAPalindrome);
    

    Second option

    public interface IPalendrome
    {
        bool IsNameAPalindrome { get; }
    }
    
    public abstract class PetBase : IPet, IPalendrome
    {
        ...
    }
    
    Console.WriteLine( ((IPalendrome)item).IsNameAPalindrome);