Declaring a indexer in a class example. - c#

When I run this program in Main() it keep giving me error messages saying that "Tommy", "Bulldog", and "Male" don't exist in current context. I couldn't figure out why? The program was running fine until I add those strings. Can anyone help me understand?
namespace indexusingthismethod
{
public class Dog
{
private string name;
private string breed;
private string gender;
public Dog()
{
name = "Fido";
breed = "Mongrel";
gender = "Male";
}
public Dog(string dogName, string dogBreed, string dogGender)
{
name = dogName;
breed = dogBreed;
gender = dogGender;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Breed
{
get { return breed; }
set { breed = value; }
}
public string Gender
{
get { return gender; }
set { gender = value; }
}
public string this[int index]
{
set
{
switch (index)
{
case 0: name = value;
break;
case 1: breed = value;
break;
case 2: gender = value;
break;
default: throw new ArgumentOutOfRangeException("index");
}
}
get
{
switch (index)
{
case 0: return name;
case 1: return breed;
case 2: return gender;
default: throw new ArgumentOutOfRangeException("index");
}
}
}
public void Bark()
{
Console.WriteLine("{0} said: Woof!", name);
}
}
public class Doggies
{
static void Main()
{
Dog descriptionofDog = new Dog();
Console.WriteLine("Dog name: {0}\nDog breed: {1}\nDog gender: {2}\n", descriptionofDog [0], descriptionofDog [1],
descriptionofDog [2]);
descriptionofDog[0] = Tommy;
descriptionofDog[1] = Bulldog;
descriptionofDog[2] = Male;
Console.WriteLine("Dog name: {0}\nDog breed: {1}\nDog gender: {2}\n",descriptionofDog[0], descriptionofDog[1],
descriptionofDog[2]);

Dog has 3 string properties on it. Name, Breed and Gender.
When you built up the descriptionofDog object, you left off the quotes which told the compiler that these are objects, not strings.
Just put quotes around your string literals:
descriptionofDog[0] = "Tommy";
descriptionofDog[1] = "Bulldog";
descriptionofDog[2] = "Male";

To add to the #paq...'s answer. Following are the easier way to create new Dog object instead of using indexer.
Dog descriptionofDog = new Dog();
or
descriptionofDog = new Dog("Tommy", "Bulldog", "Male");
or
descriptionofDog =
new Dog() { Name = "Tommy", Breed = "Bulldog", Gender = "Male" };

Related

Concatenate properties with index in c#

I have a class Student with properties sub1,sub2, and sub3.
I want to access those properties using a loop by concatenating the property name
with an index in order to avoid duplication. I tried below code
public class SampleApplication
{
public static void Main(string[] args)
{
Student s =new Student();
for(int i=1;i<=3;i++)
{
s.$"sub{i}"="Subjects";
}
}
}
public class Student
{
public string sub1;
public string sub2;
public string sub3;
}
But I am getting an error like the identifier expected.
Can anyone help me to solve this? Thanks in advance.
You need either use reflection or define an indexer:
public class Student
{
public string sub1;
public string sub2;
public string sub3;
public string this[int index]
{
get => index switch
{
1 => sub1,
2 => sub2,
3 => sub3,
_ => throw new ArgumentOutOfRangeException()
};
set
{
switch (index)
{
case 1:
sub1 = value;
break;
case 2:
sub2 = value;
break;
case 3:
sub3 = value;
break;
default: throw new ArgumentOutOfRangeException();
}
}
}
}
And usage:
Student s = new Student();
for (int i = 1; i <= 3; i++)
{
s[i] = "Subjects";
}

"Stack overflow. Repeat 261929 times[...]" is the error message when I have debugged my code then I do not see any issues so what should I do?

I have coded every line with appropriate things, however, I received an error when I tested after selecting one of the five options from the menu which is prompting the user to choose it for register dog and so on. Therefore, I am unable to recognize any wrong with my code yet I did debug and tested it many times. I do not know what to do with it even though I checked to ensure every case is not overlapped without having a "break;".
In short, I am not sure what to do with my code since I received this specific error message. Once again, I debugged my code and it doesn't show any error except this error message when I run my code.
Repeat 261929 times:
--------------------------------
at Dog.set_Name(System.String)
--------------------------------
at Dog..ctor(System.String, System.String, Int32, System.String)
at Program.<Main>$(System.String[])
Class:
public class Dog
{
public string Name { get
{
return Name;
}
set
{
Name = value;
}
}
public string Breed { get
{
return Breed;
}
set
{
Breed = value;
}
}
public int Age { get
{
return Age;
}
set
{
Age = value;
}
}
public string Vaccine { get
{
return Vaccine;
}
set
{
Vaccine = value;
}
}
//default constructor
public Dog()
{
Name = "N/A";
Breed = "N/A";
Age = -1;
string [] vaccine = new string[10];
}
//parameterized constructor
public Dog(string name, string breed, int age, string vaccine)
{
Name = name;
Breed = breed;
Age = age;
Vaccine = vaccine;
}
public string AddVaccine (string vaccine)
{
return vaccine;
}
}
Object:
//set size of the array for dogs and vaccines
Dog[] dogs = new Dog[20];
string [] vaccine = new string[10];
bool repeat = true;
while(repeat)
{
//show all menu
Console.WriteLine("1. Add a new dog\n2. Remove a dog\n3. Add Vaccine\n4. List all dogs\n5. Exit\n");
Console.Write("Selection: ");
int selection = int.Parse(Console.ReadLine());
switch(selection)
{
case 1:
//ask the user for the info about the car so we can add it to the object
Console.Write("Enter dog name: ");
string name = Console.ReadLine();
Console.Write("Enter dog breed: ");
string breed = Console.ReadLine();
Console.Write("Enter dog age: ");
int age = int.Parse(Console.ReadLine());
//finding an available location in the list
for(int i = 0; i < dogs.Length; i++)
{
if(dogs[i] == null)
{
dogs[i] = new Dog(name, breed, age, string.Empty);
Console.WriteLine("Dog successfully added");
break;
}
}
break;
case 2:
Console.Write("Enter the dog name:");
string dogName = Console.ReadLine();
bool removed = false;
for(int i = 0; i< dogs.Length; i++)
{
Dog dog = dogs[i];
if(dog!=null && dog.Name == dogName)
{
dog = null;
dogs[i] = dog;
removed = true;
Console.WriteLine("{0} was successful removed", dogName);
break;
}
if (!removed)
{
Console.WriteLine("{0} was not found", dogName);
}
}
break;
case 3:
Console.Write("Enter the dog name:");
string name2 = Console.ReadLine();
bool added = false;
for(int i = 0; i< dogs.Length; i++)
{
Dog dog = dogs[i];
if(dog!=null && dog.Name == name2)
{
Console.Write("Enter the vaccine name:");
string vac = Console.ReadLine();
if(vac == null)
{
Console.WriteLine("Vaccine not added");
}
else
{
dog.Vaccine = vac;
added = true;
Console.WriteLine("{0} was successful added", vac);
break;
}
break;
}
if (!added)
{
Console.WriteLine("{0} was not found", name2);
}
}
break;
case 4:
bool listIsEmpty = true;
foreach(Dog dog in dogs)
{
if(dog != null)
{
ShowDogInfo(dog);
listIsEmpty = false;
}
}
if(listIsEmpty)
{
Console.WriteLine("No dogs in the list");
}
break;
case 5:
Console.WriteLine("Thank you for using Rochester Doggie System");
repeat = false;
break;
default:
Console.WriteLine("Invalid selection");
break;
}
}
void ShowDogInfo(Dog dog)
{
Console.WriteLine("Name: {0}", dog.Name);
Console.WriteLine("Breed: {0}", dog.Breed);
Console.WriteLine("Age: {0}", dog.Age);
Console.WriteLine("Vaccine: {0}", dog.Vaccine);
Console.WriteLine();
}
Name = value;: in the setter, you call the setter, which calls the setter etc.
This results in the observed stack overflow.
Change your properties to auto-properties:
public class Dog
{
public string Name { get; set; }
// etc.
}

Returning multiple parameters

I'm trying to return multiple parameters, if that's how to word it. I'm trying to "translate" Python code into C#.
I'm actually not quite sure what exact term I'm searching for, but I know how to do it in Python so I'll just show my code.
class Staff
{
public String name;
public int age;
/* Now in Python, you can easily write this following, but I have no
idea how this works in C#. I basically want to return all the values
for each employee in the "Staff" class */
def desc(self):
desc_str = "%s is %s years old." % (self.name, self.age)
return desc_str
}
class Program
{
public static void Main()
{
Staff Jack = new Staff();
Jack.name = "Jack";
Jack.age = 40;
Staff Jill = new Staff();
Jill.name = "Jill";
Jill.age = 50;
Console.WriteLine(Jack.desc());
Console.WriteLine(Jill.desc());
Console.ReadKey();
}
}
EDIT: I figured out that what I was searching for was get, set and ToString() and will look into it now.
The code I've translated looks like the following now:
class Staff
{
private string name;
private int age;
private string yearsold = " years old.";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public string YearsOld
{
get
{
return yearsold;
}
set
{
yearsold = value;
}
}
public override string ToString()
{
return "Employee " + Name + " is " + Age + YearsOld;
}
}
class TestPerson
{
static void Main()
{
// Create a new Person object:
Staff person = new Staff();
person.Name = "Jack";
person.Age = 40;
Console.WriteLine(person);
person.Name = "Jill";
person.Age = 50;
Console.WriteLine(person);
Console.ReadKey();
}
}
Since you have a class, you can override the ToString function and use the string.Format function like so:
class Staff
{
public string name;
public int age;
public Staff(string _name, int _age)
{
this.name = _name;
this.age = _age;
}
public override string ToString()
{
return string.Format("{0} is {1} years old.", this.name, this.age);
}
}
Then to print:
Staff Jack = new Staff("Jack", 40);
Console.WriteLine(Jack); // implicitly calls Jack.ToString()
Hope that helps.

Variable as function parameter?

I am doing a sort of little rpg(role playing game), in the conversations there are decisions that influence certain variables of the player. I was wondering if you knew a more effective way than mine:
public string Name, Nickname;
public int Age;
public void Decision(string Var, string Input)
{
if (Var == "Name")
Name = Input;
else if (Var == "Nickname")
Nickname = Input;
else if (Var == "Age")
Age = Convert.ToInt32(Input);
}
As you can see, it is pretty long for only 3 variables, but there are more... Is there a way to do it faster? Something like this:
public void Decision(Variable Var, string Input)
{
Player.Var = input;
}
Edit: I will use a mix of the two answers:
public string Nom, Prenom;
public int Age;
public void Decision(InfoType type, string Input)
{
switch (type)
{
case InfoType.Name:
Nom = Input;
break;
case InfoType.Prenom:
Prenom = Input;
break;
}
}
public void Decision(InfoType type, int Input)
{
switch (type)
{
case InfoType.Age:
Age = Convert.ToInt32(Input);
break;
}
}
How about method overloading?
public void Decision(string Var, string Input)
{
if (Var == "Name")
Name = Input;
else if (Var == "Nickname")
Nickname = Input;
}
public void Decision(int Input)
{
Age = input
}
You could possibly use reflection. The downside to this is you will have to do additional checks for complex types, but for simple objects it can work like this.
public class MyObject {
public string Name { get; set; }
public string Nickname { get; set; }
public int Age { get; set; }
}
public class TestReflection {
public void Test() {
var obj = new MyObject();
UpdateObject(obj, "Name", "THis is a name");
UpdateObject(obj, "Age", 99);
UpdateObject(obj, "Nickname", "This is a nickname");
Console.WriteLine("{0} {1} {2}", obj.Name, obj.Age, obj.Nickname);
Console.ReadLine();
}
private void UpdateObject(MyObject obj, string varName, object varValue) {
//Get Properties of the object
var properties = obj.GetType().GetProperties();
//Search for the property via the name passed over to the method.
var prop = properties.FirstOrDefault(_ => _.Name.Equals(varName, StringComparison.InvariantCultureIgnoreCase));
//Check prop exists and set to the object.
if(prop != null) {
prop.SetValue(obj, varValue);
}
}
}
You could make things a little bit more concise with a switch statement and also use an enum for type safety. e.g.
public enum InfoType {
Name,
Nickname,
Age
}
public void Decision(InfoType type, string input)
{
switch (type)
{
case InfoType.Name:
Name = input;
break;
case InfoType.NickName:
NickName = input;
break;
}
}
And so on.

How to Create a simple atm program in c# using inheritance

I'm trying to create an e-ATM console app using C# using inheritance, but every time I debug I see that the derived class values are null, whereas the base class fields or properties are filled with values. Why is the derived class not showing the list with their data even after it is inherited from the base class?
class CreateAccount
{
string firstName, lastName, dateOfBirth, phoneNO, fathersName, mothersName;
double initialBalance; int pinNo = 100, accountNo = 1234, age; DateTime yearOfBirth;
protected static List<CreateAccount> data = new List<CreateAccount>();
protected string FirstName
{
get { return this.firstName; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else firstName = value;
}
}
protected string LastName
{
get { return this.lastName; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else lastName = value;
}
}
protected string DateOfBirth
{
get { return this.dateOfBirth; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else dateOfBirth = value;
}
}
protected string PhoneNo
{
get { return this.phoneNO; }
set
{
if ((string.IsNullOrEmpty(value)) || value.Length != 10)
throw new Exception();
else
phoneNO = value;
}
}
protected string FathersName
{
get { return this.fathersName; }
set
{
if (string.IsNullOrEmpty(value))
throw new Exception();
else
fathersName = value;
}
}
protected string MothersName
{
get { return this.mothersName; }
set
{
if (string.IsNullOrEmpty(value))
throw new Exception();
else
mothersName = value;
}
}
protected double InititailBalance
{
get { return this.initialBalance; }
set
{
if (double.IsNaN(value))
throw new Exception();
else
initialBalance = value;
}
}
protected int PinNo
{
get { return this.pinNo; }
}
protected int AccountNo
{
get { return this.accountNo; }
}
public void GenerateAccount()
{
// code for asking user for their details.
data.Add(this);
}
}
class ATM :CreateAccount
{
public void Deposit()
{
Console.WriteLine("Enter your account number");
int accountNo = int.Parse(Console.ReadLine());
if (accountNo == AccountNo)
{
Console.WriteLine("Enter your amount you wish to deposit");
int amount = int.Parse(Console.ReadLine());
InititailBalance+= amount;
}
}
}
class Program
{
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Menu");
Console.WriteLine("1.Create Account");
Console.WriteLine("2.ATM");
Console.Write("Please enter your selections: ");
int select = int.Parse(Console.ReadLine());
switch (select)
{
case 1:
CreateAccount account = new CreateAccount();
account.GenerateAccount();
break;
case 2:
ATM atm = new ATM();
atm.Deposit();
break;
}
}
}
}
You are creating two different objects: a 'CreateAccount' Object and an 'ATM' object.
An ATM object does not automatically inherit the values from a previously created CreateAccount object, they are two completely different, unrelated entities.
So for your ATM object to have the same values that your CreateAccount object has, you would have to copy the CreateAccount object to your ATM object.
CreateAccount account = new CreateAccount();
//set account variables here
ATM atm = (ATM)account;
Here is how it's done with proper use of inheritance which is useless in this case actually. Dictionary is the proper datastructure to use in this case because you can avoid duplicates with it. Also from this code you might want to remove the accountNo from Account class to avoid duplicate numbers being kept and the ask it beffore calling GenerateAccount() method. So this is full console app:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ATM
{
class Account
{
string firstName, lastName, dateOfBirth, phoneNO, fathersName, mothersName;
double initialBalance;
int pinNo, accountNo, age;
DateTime yearOfBirth;
public Account()
{
pinNo = 100;
accountNo = 1234;
}
public string FirstName
{
get { return this.firstName; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else firstName = value;
}
}
public string LastName
{
get { return this.lastName; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else lastName = value;
}
}
public string DateOfBirth
{
get { return this.dateOfBirth; }
set
{
if (string.IsNullOrEmpty(value)) throw new Exception();
else dateOfBirth = value;
}
}
public string PhoneNo
{
get { return this.phoneNO; }
set
{
if ((string.IsNullOrEmpty(value)) || value.Length != 10)
throw new Exception();
else
phoneNO = value;
}
}
public string FathersName
{
get { return this.fathersName; }
set
{
if (string.IsNullOrEmpty(value))
throw new Exception();
else
fathersName = value;
}
}
public string MothersName
{
get { return this.mothersName; }
set
{
if (string.IsNullOrEmpty(value))
throw new Exception();
else
mothersName = value;
}
}
public double InititailBalance
{
get { return this.initialBalance; }
set
{
if (double.IsNaN(value))
throw new Exception();
else
initialBalance = value;
}
}
public int PinNo
{
get { return this.pinNo; }
}
public int AccountNo
{
get { return this.accountNo; }
}
public void GenerateAccount()
{
// code for asking user for their details.
}
}
class ATM
{
public static Dictionary<int, Account> AccountsList;
static ATM()
{
AccountsList = new Dictionary<int, Account>();
}
public void CreateAccount()
{
Account acc = new Account();
acc.GenerateAccount();
AccountsList.Add(acc.AccountNo, acc);
}
public void Deposit()
{
Console.WriteLine("Enter your account number");
int accountNo = int.Parse(Console.ReadLine());
if (AccountsList.ContainsKey(accountNo))
{
Console.WriteLine("Enter your amount you wish to deposit");
int amount = int.Parse(Console.ReadLine());
AccountsList[accountNo].InititailBalance += amount;
}
}
}
class Program
{
static void Main(string[] args)
{
ATM atm = new ATM();
while (true)
{
Console.WriteLine("Menu");
Console.WriteLine("1.Create Account");
Console.WriteLine("2.ATM");
Console.Write("Please enter your selections: ");
int select = int.Parse(Console.ReadLine());
switch (select)
{
case 1:
atm.CreateAccount();
break;
case 2:
atm.Deposit();
break;
default:
Console.WriteLine("Invalid selection!");
break;
}
}
}
}
}
CreateAccount is an operation of Atm and this is why I don't think you should be using inheritance. I propose this solution:
Class Account:
class Account
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public string PhoneNumber { get; set; }
public double Balance { get; set; }
// More properties here
...
}
Class Atm:
class Atm
{
public List<Account> Accounts { get; set; }
public Atm()
{
Accounts = new List<Account>();
}
public void CreateAccount()
{
var account = new Account();
// Get details from user here:
...
account.Balance = 0.0;
account.Id = Accounts.Count + 1;
Accounts.Add(account);
}
public void Deposit()
{
int accountId;
// Get input from the user here:
// --------------------------------
// 1. Check that the account exists
// 2. Deposit into the account.
...
}
Full example:
class Program
{
static void Main()
{
var atm = new Atm();
while (true)
{
int option;
Console.WriteLine();
Console.WriteLine("Menu:");
Console.WriteLine("1. Create Account");
Console.WriteLine("2. Deposit");
Console.WriteLine();
Console.Write("Please make a selection: ");
var input = int.TryParse(Console.ReadLine(), out option);
Console.WriteLine("-----------------");
switch (option)
{
case 1:
atm.CreateAccount();
break;
case 2:
atm.Deposit();
break;
}
}
}
}
class Account
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public string PhoneNumber { get; set; }
public double Balance { get; set; }
}
class Atm
{
public List<Account> Accounts { get; set; }
public Atm()
{
Accounts = new List<Account>();
}
public void CreateAccount()
{
var account = new Account();
Console.WriteLine("Create a new account!");
Console.WriteLine();
Console.Write("Enter first name: ");
account.FirstName = Console.ReadLine();
Console.Write("Enter last name: ");
account.LastName = Console.ReadLine();
Console.Write("Enter date of birth: ");
account.DateOfBirth = DateTime.Parse(Console.ReadLine());
Console.Write("Enter phone number: ");
account.PhoneNumber = Console.ReadLine();
account.Balance = 0.0;
account.Id = Accounts.Count + 1;
Accounts.Add(account);
}
public void Deposit()
{
int accountId;
Console.Write("Enter your account number: ");
int.TryParse(Console.ReadLine(), out accountId);
var account = Accounts.FirstOrDefault(a => a.Id == accountId);
if (account != null)
{
double amount;
Console.Write("Enter amount to deposit: ");
double.TryParse(Console.ReadLine(), out amount);
account.Balance += amount;
Console.Write("Your new balance is {0}", account.Balance);
}
else
{
Console.WriteLine("That account does not exist!");
}
}
}

Categories