none
What's wrong with the code? RRS feed

  • Question

  • Could anybody tell me what's wrong with the following code?

    The code segments are copied from Microsoft's C# Tutorial.

    using System;
    
    namespace Inherit3
    {
        class Program
        {
            static void Main(string[] args)
            {
                BankAccount account = new BankAccount("Ben", 10000);
                account.MakeWithdrawal(500, DateTime.Now, "Rent payment");
                Console.WriteLine(account.Balance);
                account.MakeDeposit(100, DateTime.Now, "Friend paid me back");
                Console.WriteLine(account.Balance);
                account.GetAccountHistory();
                Console.WriteLine(account.Report);
            }
    
        }
    }
    

    using System;
    using System.Collections.Generic;
    
    namespace Inherit3
    {
        public class Transaction
        {
            public decimal Amount { get; }
            public DateTime Date { get; }
            public string Notes { get; }
            public Transaction(decimal amount, DateTime date, string note)
            {
                this.Amount = amount;
                this.Date = date;
                this.Notes = note;
            }
        }
        public class BankAccount
        {
            public string Report { get; set; }
            public decimal InitialBalance { get; set; }
            public string Number { get; }
            public string Owner { get; set; }
            public decimal Balance
            {
                get
                {
                    decimal balance = InitialBalance;
                    foreach (var item in allTransactions)
                    {
                        balance += item.Amount;
                    }
                    return balance;
                }
            }
            private List<Transaction> allTransactions = new List<Transaction>();
            private static int accountNumberSeed = 1234567890;
            public virtual void PerformMonthEndTransactions() { }
            public BankAccount(string name, decimal initialBalance)
            {
                this.Number = accountNumberSeed.ToString();
                accountNumberSeed++;
                this.Owner = name;
                MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
            }
            public void MakeDeposit(decimal amount, DateTime date, string note)
            {
                if (amount <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
                }
                var deposit = new Transaction(amount, date, note);
                allTransactions.Add(deposit);
            }
    
            public void MakeWithdrawal(decimal amount, DateTime date, string note)
            {
                if (amount <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
                }
                if (Balance - amount < 0)
                {
                    throw new InvalidOperationException("Not sufficient funds for this withdrawal");
                }
                var withdrawal = new Transaction(-amount, date, note);
                allTransactions.Add(withdrawal);
            }
    
            public string GetAccountHistory()
            {
                var report = new System.Text.StringBuilder();
                decimal balance = 0;
                report.AppendLine("Date\t\tAmount\tBalance\tNote");
                foreach (var item in allTransactions)
                {
                    balance += item.Amount;
                    report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
                }
                this.Report += report.ToString();
                return this.Report;
    
            }
        }
    }

    Saturday, November 21, 2020 3:56 AM

Answers

  • Your parent class does not have a default constructor. It only has a constructor that takes two parameters of type String and Decimal.

    However, in your inherited class you do not have such a constructor, so it is not possible to create an instance because the compiler would not know what values to pass to the corresponding arguments in the parent class.

    The solution is either to add a default constructor to the parent class, or add a constructor with the correct parameters to your inherited class.

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 12:52 PM
    Moderator

  • When I point my mouse to the redline. It shows "There is no argument given that corresponds to the required formal parameter 'name' of 'BankAccount.BankAccount(string, decimal)'". What does it mean?

    It means that you have not matched constructors between your base class and
    your derived class.

    (1) Your derived class only has a default ctor which takes no arguments.

    (2) Your base class only has a ctor which takes two arguments.

    Possible solutions:

    (1) Add a ctor to your base class which takes no arguments.

    OR

    (2) Add a ctor to your derived class which takes the same two arguments
    as the base class ctor.

    (Or maybe both.)

    - Wayne

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 12:55 PM

  • (2) Add a ctor to your derived class which takes the same two arguments
    as the base class ctor.

    Example:

    class ccString : BankAccount
    {
        public ccString(string name, decimal initialBalance) : base(name, initialBalance) { }
    

    - Wayne

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 1:16 PM

All replies

  • Could anybody tell me what's wrong with the following code?

    The code segments are copied from Microsoft's C# Tutorial.

    You should post a link to the example being used.

    The code in your pic appears wrong as you have it directly in a namespace when
    it needs to be in a class.

    - Wayne

    Saturday, November 21, 2020 8:08 AM
  • Could anybody tell me what's wrong with the following code?

    I see several wrong things.

    The first one has already been pointed out in a previous answer: you are writing a method directly inside a namespace. You are missing a class in between the namespace and your method.

    Second: You have public override void () : ... It is missing a name. You need something after the "void" and before the parentheses.

    Third: It has ": base()". You would use this with a constructor, but the "thing" that you are writing is not a constructor, because it has "override" and "void".

    Fourth: You are calling "Balance". But there is nothing with that name declared anywhere.

    The code below that is underlined in red most likely because of the missing class and method name. Once you have fixed this, the underlined errors should go away.

    Saturday, November 21, 2020 11:38 AM
    Moderator
  • Dear Alberto,

    Here are the response to the mistakes that you pointed out:

    • Mistake 1: Agreed

    • Mistake 2: Agreed

    • Mistage 3: "Balance" in my code is a property of its parent class "BankAccount". If calling a property needs a declaration, how to call a property of the parent class without losing it value.


    Questions:

    I have a question about the key word ": base()". If it means the class "BankAccount()", why not ": BankAccount()". If there are 2 classes, say BankAccount() and Class2(), in the same namespace, how do I know which class I am subclassing.

    Sunday, November 22, 2020 3:14 AM
  • "Balance" in my code is a property of its parent class "BankAccount"

    No, unfortunately it was not a property of your parent class. You did not have a parent class in your code. In fact, you didn't have any class at all, which was the main cause of errors.

    If you had had a parent class, and the variable was declared in the parent class, then it is correct to access it like you were using it.

    I have a question about the key word ": base()". If it means the class "BankAccount()", why not ": BankAccount()". If there are 2 classes, say BankAccount() and Class2(), in the same namespace, how do I know which class I am subclassing.

    If there are two classes, their namespace is irrelevant. A class in any namespace can inherit from another class in any namespace. You indicate the parent class after a colon in the declaration of your class, such as:

    class CurrentAccount : BankAccount

    Here you are saying that BankAccount is the parent of CurrentAccount. Note that both classes do not need to be in the same namespace, as long as your using statements declare the required namespaces.

    Since in C# there is only single inheritance (multiple inheritance is not allowed) then by writing base() you always know which class it refers to. It is the one that was written after the colon. Of course, this will fail (like everything else) if you forget to add the class declaration in your code.

    Sunday, November 22, 2020 7:46 AM
    Moderator
  • Hi Alberto,

    Sorry for the mistake that you pointed out, I have revised the code as follows. Is there any mistake?

       No, unfortunately it was not a property of your parent class.

    In my view, since PerformMonthEndTransactions is a subclass of BankAccount, all properties of the parent class BankAccount will be available in its subclass. Anything wrong?

    Monday, November 23, 2020 3:48 AM

  • I have revised the code as follows. Is there any mistake?


    Why are you putting arguments on the class declaration? They will go on a
    constructor definition. Review:

    Classes (C# Programming Guide)
    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/classes

    - Wayne

    Monday, November 23, 2020 4:42 AM
  • In the first one, you are inheriting from BankAccount. But you have not told the compiler how to find BankAccount. It should either be in the same namespace, or if it is in a different one, you have to either write the namespace before the name of the class separated with a dot, or mention the namespace in a using directive. Since your code does not do either of these, the compiler cannot find BankAccount and marks it as an error. And therefore, anything that you expected to inherit from BankAccount is also in error.

    > In my view, since PerformMonthEndTransactions is a subclass of BankAccount,

    Well, it would be, if you were indeed inheriting from BankAccount. But since you wrote BankAccount in such a way that it cannot be found, then the compiler does not recognize anything that is in this class that from its point of view does not exist.

    Monday, November 23, 2020 2:16 PM
    Moderator
  • Dear Alberto,

    1. Actually the subclass PerformMonthEndTransactions and parent class BankAccount are in the same namespace Inherit3 
    2. I try to follow your instructions to add Inherit3. before "BankAccount", but it doesn't help.

    Parent class



    • Edited by BenTam Tuesday, November 24, 2020 3:56 AM
    Tuesday, November 24, 2020 3:53 AM
  • Dear Wayne,

    Thanks for your reply. I try to remove the arguments, but it doesn't help.

    Tuesday, November 24, 2020 4:02 AM
  • Actually the subclass PerformMonthEndTransactions and parent class BankAccount are in the same namespace Inherit3 

    Forget the namespace. It is irrelevant. It does not do anything to connect the classes. It does not provide inheritance.

    The inheritance is determined by the class name that you write after the colon, which you are still not writing.

    When you write

    class One : Two

    This indicates that class One inherits from class Two.

    If you do not write it, then there is no inheritance. The namespace does not matter. Forget about the namespace. It does not have any effect on inheritance.

    Tuesday, November 24, 2020 12:37 PM
    Moderator

  •  I try to remove the arguments, but it doesn't help.

    Removed the arguments from where? In the code you posted you have specified
    arguments (parameters) on the *class* declaration statement:

    class ProgramMonthEndTransactions(string name, decimal Balance) : BankAccount(string name, decimal Balance)

    They should not be there:

    class ProgramMonthEndTransactions : BankAccount

    Arguments/parameters should appear on the constructors and methods *within*
    that class, whether they are specific to this class or inherited from the
    base class (overridden).

    You seem to be doing a lot of changes based on guessing rather than based on
    an understanding of how classes and inheritance work.

    >it doesn't help.

    Doesn't help with what?

    That sounds like you are making a mistake that is very common for many who are
    learning programming: assuming that one fix or change is all that is needed to
    eliminate all errors. So they are told that they need to change something and 
    when they do that but still see errors they mistakenly believe that the change 
    wasn't needed or that it was wrong because they then see new errors.

    As you should have gathered from Alberto's comments, you have multiple
    problems in the code you have been posting. Each of those problems needs to
    be corrected. Just because all errors don't go away when you make one change,
    or the compiler shows new errors, doesn't mean that the change isn't needed.

    - Wayne


    • Edited by WayneAKing Wednesday, November 25, 2020 12:43 PM spelling
    Tuesday, November 24, 2020 6:28 PM
  • Dear Wayne and Alberto,

    Actually I posted the screen capture of both code of the subclass and parent class, but the screen capture of the subclass is lost. I am happy to post more that you need.

    Subclass code

    Parent class



    • Edited by BenTam Wednesday, November 25, 2020 9:24 AM
    Wednesday, November 25, 2020 9:05 AM

  • Subclass code


    First off, pay attention to what the compiler is telling you.

    The red lines indicate errors. If you place the mouse cursor on one of those
    red lines you will see a popup error message telling you what is wrong.

    For example, the red line under PerformMonthEndTransactions will show a message
    that probably tells you that you can't have a member method name that is the 
    same as the class name. (Obviously a constructor will have the same name.)

    - Wayne

    Wednesday, November 25, 2020 1:16 PM
  • I believe that there is another mistake in addition to what Wayne told you.

    As Wayne said, the parent class declares a virtual method called PerformMonthEndTransactions. And you had the misfortune of naming your child class with the same name as the method.

    But additionally, inside the class you have a confusion between methods and constructors. You have a member that is called PerformMonthEndTransactions. But it is marked as "override", which is only allowed on a method, and it also has ": base()", which is only allowed for a constructor. So it will not work as either a method or a constructor.

    Wednesday, November 25, 2020 1:54 PM
    Moderator
  • Dear Alberto and Wayne,

    I change the class name to ccString. There is no change to other code. However its redlined. I am a beginner in C#. Could you help me to solve the problem.


    Thursday, November 26, 2020 4:23 AM

  • I change the class name to ccString. There is no change to other code. However its redlined. 

    When you place the mouse cursor on the red line, what does the popup message say?

    - Wayne

    Thursday, November 26, 2020 4:30 AM
  • [...] However its redlined.

    [...] I am a beginner in C#

    Especially if you are a beginner, it is very important that you pay attention to the messages that the compiler gives you, since they are usually very informative (with some exceptions, admittedly) and they explain exactly what is wrong.

    So it is not enough to say "it is underlined" or "I get an error". It is very important to examine the complete, precise and exact error message. There are two places where you can see it: either hover the mouse pointer over the underlined word and a message will pop up, or look at the bottom of Visual Studio, in the compilation errors tab, where the errors will be listed preceded by a red icon.

    Thursday, November 26, 2020 8:50 AM
    Moderator
  • Hi Wayne and Alberto,

    When I point my mouse to the redline. It shows "There is no argument given that corresponds to the required formal parameter 'name' of 'BankAccount.BankAccount(string, decimal)'". What does it mean?

    Thursday, November 26, 2020 10:25 AM
  • Your parent class does not have a default constructor. It only has a constructor that takes two parameters of type String and Decimal.

    However, in your inherited class you do not have such a constructor, so it is not possible to create an instance because the compiler would not know what values to pass to the corresponding arguments in the parent class.

    The solution is either to add a default constructor to the parent class, or add a constructor with the correct parameters to your inherited class.

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 12:52 PM
    Moderator

  • When I point my mouse to the redline. It shows "There is no argument given that corresponds to the required formal parameter 'name' of 'BankAccount.BankAccount(string, decimal)'". What does it mean?

    It means that you have not matched constructors between your base class and
    your derived class.

    (1) Your derived class only has a default ctor which takes no arguments.

    (2) Your base class only has a ctor which takes two arguments.

    Possible solutions:

    (1) Add a ctor to your base class which takes no arguments.

    OR

    (2) Add a ctor to your derived class which takes the same two arguments
    as the base class ctor.

    (Or maybe both.)

    - Wayne

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 12:55 PM

  • (2) Add a ctor to your derived class which takes the same two arguments
    as the base class ctor.

    Example:

    class ccString : BankAccount
    {
        public ccString(string name, decimal initialBalance) : base(name, initialBalance) { }
    

    - Wayne

    • Marked as answer by BenTam Friday, November 27, 2020 5:05 AM
    Thursday, November 26, 2020 1:16 PM
  • Hi Alberto and Wayne,

    Thank you a lot for your tips.

    Friday, November 27, 2020 5:06 AM