C #: hidden base method used when an object is passed as an argument. Any workaround?

I am new to inheritance. I noticed that if you take an object that was created from a partial class and pass it as an argument to a function that takes its base type, the base methods are used even if they were hidden in the partial class.

It would be helpful to be able to use inherited objects interchangeably. Is there a workaround or alternative in the language that would allow me to pass objects as arguments in this way?

I wrote some sample code to demonstrate what I am talking about:

public class Enemy
{
    string[] baseLikes = new string[] { "loitering", "puppies" };

    public string[] GetLikes()
    {
        return baseLikes;
    }
}

public partial class Skater : Enemy
{
    string[] uniqueLikes = new string[] { "skateboarding" };

    public new string[] GetLikes()
    {
        string[] likes = base.GetLikes();
        return likes.Concat(uniqueLikes).ToArray();
    }
}

class Program
{
    public static void WriteEnemyLikes(Enemy enemy)
    {
        string[] likes = enemy.GetLikes();
        Console.WriteLine("This enemy likes: ");
        foreach (string like in likes)
            Console.WriteLine("- " + like);
    }

    static void Main(string[] args)
    {
        Skater skater = new Skater();
        WriteEnemyLikes(skater);

        Console.ReadLine();

        // Output:
        // This enemy likes:
        // - loitering
        // - puppies

        // Notably absent: skateboarding
    }
}

      

+3


source to share


3 answers


You inherit all rights.

First of all; you should almost never use the hide method. It just has no practical purpose. To allow a derived object to override the functionality of the base class (concept called polymorphism), you use the keyword override

and virtual

in the base class:



public class Enemy
{
    string[] baseLikes = new string[] { "loitering", "puppies" };

    public virtual string[] GetLikes()
    {
        return baseLikes;
    }
}

public class Skater : Enemy
{
    string[] uniqueLikes = new string[] { "skateboarding" };

    public override string[] GetLikes()
    {
        string[] likes = base.GetLikes();
        return likes.Concat(uniqueLikes).ToArray();
    }
}

      

If you still want to use a base class method in a derived class, call it with base()

. There is also no reason to have a derived class partial

unless you want to define a different part of it in a different file. The real reason for the classes partial

is the generated code, and that doesn't happen here.

+10


source


There are some serious problems in the code:



  • partial

    does not do what you think

    partial

    is intended to split a class declaration into multiple places (or files). It has nothing to do with inheritance.

  • You must use methods virtual

    .

    Declare the method in the base class as you would virtual

    use override

    in the derived class. Methods will only demonstrate the behavior you want, i.e. That the method call will depend on the type of the instance and not on the static type of the variable:

    public class Enemy
    {
        string[] baseLikes = new string[] { "loitering", "puppies" };
    
        public virtual string[] GetLikes()
        {
           return baseLikes;
        }
    }
    
    public class Skater : Enemy
    {
        string[] uniqueLikes = new string[] { "skateboarding" };
    
        public override string[] GetLikes()
        {
            string[] likes = base.GetLikes();
            return likes.Concat(uniqueLikes).ToArray();
        }
    }
    
          

  • new

    is intended to indicate that a method is hidden from a base class in a derived class. The method will only be called if you are using a derived class variable (it is statically set).

+6


source


The other answers are banging a nail on the head: inheritance doesn't work the way you think. They are all great answers, I just want to expand my answers a bit and make a suggestion to help simplify your code.

Instead of using the [] string and method GetLikes()

, have you considered using a property List<string>

?

For example:

public class Enemy
{
    public List<string> Likes { get; set; }

    public Enemy()
    {
        Likes = new List<string>()
        { 
            "loitering", 
            "puppies" 
        };
    }
}

public partial class Skater : Enemy
{
    public Skater()
    {
        Likes.Add("skateboarding");
    }
}

      

With this approach, you can have one property that everyone "loves" without the need for a method. Also, you don't need to override any virtual method.

I've created a script here that shows it in action.

0


source







All Articles