Вызов переопределенного метода, используемого для базового типа - PullRequest
0 голосов
/ 05 июля 2018

В этом коде:

using System;

namespace ConsoleApp1
{
    public class TextInput
    {
        protected string _text = "";

        public void Add(char c)
        {
            _text += c;
        }

        public string GetValue()
        {
            return _text;
        }
    }


    public class NumericInput : TextInput
    {
        public new void Add(char c)
        {
            if (!char.IsDigit(c)) return;
            _text += c;
        }
    }


    public class Program
    {
        public static void Main(string[] args)
        {
            TextInput input = new NumericInput();
            input.Add('1');
            input.Add('a');
            input.Add('0');
            Console.WriteLine(input.GetValue());

            Console.WriteLine(char.IsDigit('1'));
            Console.WriteLine(char.IsDigit('a'));
            Console.WriteLine(char.IsDigit('0'));
        }
    }
}

... вызов Console.WriteLine(char.IsDigit('a')); возвращает корректно False, но в переопределенном методе Add он всегда возвращает True.

Очевидно, он вызывает TextInput.Add() вместо NumericInput.Add(). Можно ли это исправить внутри переопределенного метода Add()? Код в Main может не изменяться!

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Если вы хотите реализовать переопределение метода, используйте ключевое слово virtual в базовом классе и ключевое слово override в производном классе.

namespace ConsoleApp1
{
    public class TextInput
    {
        protected string _text = "";
        //Virtual allows derived class to enhance its functionality.
        public virtual void Add(char c)
        {
            _text += c;
        }
        ....
    }


    public class NumericInput : TextInput
    {
        //Override function will add more functionality to base class function
        public override void Add(char c)
        {
            if (!char.IsDigit(c)) return;
            _text += c;
        }
    }

Теперь ключевое слово new не переопределяет функцию базового класса, оно скрывает функциональность базового класса.

Если вы хотите переопределить функцию в производном классе, тогда используйте override вместо new ключевое слово

Для получения дополнительной информации посетите: Поток Stackoverflow

0 голосов
/ 05 июля 2018

почему вы не используете абстрактный класс:

, поскольку у нас есть несколько реализаций add, и мы не можем использовать операторы на T, объявите их как абстрактные и реализуйте на производных классах

public abstract class Input<T>
    {
        protected T __input;
        public abstract void Add(T c);
        public T GetValue()
        {
            return __input;
        }
    }
    public class NumericInput : Input<int>
    {
        public override void Add(int c)
        {
            __input += c;
        }
    }
    public class TextInput : Input<string>
    {
        public override void Add(string c)
        {
            __input += c;
        }
    }

static void Main(string[] args)
        {
            var input = new NumericInput();
            input.Add(1);
            input.Add(2);
            Console.WriteLine(input.GetValue());

            var text = new TextInput();
            text.Add("a");
            text.Add("a");
            text.Add("a");
            Console.WriteLine(text.GetValue());

            Console.ReadLine();
        }
0 голосов
/ 05 июля 2018

Проверьте разницу между new и override в c #. Кроме того, взгляните на виртуальный ключ.

Я не собираюсь сейчас это объяснять. Здесь и в Интернете много информации об этом.

MS документы: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords

Более подробная информация здесь: Разница между новым и переопределить

Чтобы подвести итог, используйте переопределение в этом случае. Попробуйте оба, и вы поймете, как они работают. Там

...