-2

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;
    }
}
Hina Khuman
  • 757
  • 3
  • 14
  • 41
  • House is a type that inherits from `List`, why would it know anything about your `IsNameAPalindrome()` method? – maccettura Oct 17 '22 at 21:06
  • Also, _why_ is `House` inheriting from a List? Shouldn't you just create a variable called house that is a `List`? I dont see the need for inheritance/a new type here. – maccettura Oct 17 '22 at 21:07
  • The problem is that you need to specify the `IsNameAPalindrome` property in the interface as wel. – Jeroen van Langen Oct 17 '22 at 21:07
  • while adding derived classes are added to the list with inherits PetBase. Also, the constraint was to add a piece of code within Print() method – Hina Khuman Oct 17 '22 at 21:07
  • 2
    Buy your list says, "i'm containing objects that have implemented IPet", which doesn't contains the IsNameAPalindrome property. – Jeroen van Langen Oct 17 '22 at 21:09
  • 2
    Side note: please check out https://stackoverflow.com/questions/5376203/inheriting-from-listt#comment6078579_5376218 before continuing with the `House : List` – Alexei Levenkov Oct 17 '22 at 21:23
  • 1
    Also please re-read the [mre] guidance on posting code - 90% of the code shown is not related to your question which is "why I can't access method of some class that implements `IPet` interface via reference to that interface". Ideally you would just show 2 implementations of `IPet` (one with extra `IsNameAPalindrome` method and another with without) and ask why `((IPet)(x ? new PetWithPalindrome() : new PetWithoutPalindromeMethod()).IsNameAPalindrome` fails to compile. – Alexei Levenkov Oct 17 '22 at 21:29

1 Answers1

1

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);
Eric J.
  • 147,927
  • 63
  • 340
  • 553