I have been trying to make a simple program to check a person's birthday and if their birthday is the same as their pet, for it to be printed out on the console, or if it's not the same to type out no valid input. I don't know why but the variables are not being taken in saying they aren't properly added or it just says they need a get/set. If anyone could show and explain how it should be done it would be like really awesome and cool and amazing. Here's the code:
using System;
namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
Human human = new Human();
human.name();
human.age();
human.id();
human.birthday();
Robot robot = new Robot();
robot.id();
robot.model();
Pet pet = new Pet();
pet.name();
pet.birthday();
Program program = new Program();
program.BirthdayCheck("","");
}
public static void BirthdayCheck(string userResponse1, string userResponse2)
{
if (userResponse1 == userResponse2)
{
Console.WriteLine("" + userResponse1);
}
else
{
Console.WriteLine("No matching birthday");
}
}
interface IHuman
{
void name();
void age();
void id();
void birthday();
}
interface IRobot
{
void model();
void id();
}
interface IPet
{
void name();
void birthday();
}
class Human : IHuman
{
public string userResponse2;
public string Birthday
{
get { return userResponse2; }
set { userResponse2 = value; }
}
public void name()
{
Console.WriteLine("Citizen name: ");
Console.ReadLine();
}
public void age()
{
Console.WriteLine("Citizen's age: ");
Console.ReadLine();
}
public void id()
{
Console.WriteLine("Citizen's id: ");
Console.ReadLine();
}
public void birthday()
{
Console.WriteLine("Citizen's birthday: ");
userResponse2 = Console.ReadLine();
}
}
class Robot : IRobot
{
public void model()
{
Console.WriteLine("Enter Robot Model: ");
Console.ReadLine();
}
public void id()
{
Console.WriteLine("Enter Robot Id: ");
Console.ReadLine();
}
}
class Pet : IPet
{
public string userResponse1;
public string Birthday
{
get { return userResponse1; }
set { userResponse1 = value; }
}
public void name()
{
Console.WriteLine("Enter pet name: ");
Console.ReadLine();
}
public void birthday()
{
Console.WriteLine("Enter pet birthday: ");
userResponse1 = Console.ReadLine();
}
}
}
}
I had no issues with the interfaces themselves and it does that the information, it just doesn't want to compare the two between them. I don't know if it's just a logical or syntax error, but hopefully, it's at least partially correct. Finished up some syntax errors but the issues still remain. The error message that appears is "Member Program.BitrhdayCheck(string, string) cannot be accessed with an instance reference; qualify it with a type name instead."
As commented above, this looks like a really complicated program to compare something so simple. Assuming that's your choice, I think these two lines in the main method are not quite correct:
Program program = new Program();
program.BirthdayCheck("","");
you really should be calling the BirthdayCheck method directly.
Another issue is, no value is really being passed to this method. So not sure exactly what is it you're comparing.
Here's a fix to your main method that can solve your issue:
static void Main(string[] args)
{
Human human = new Human();
human.name();
human.age();
human.id();
human.birthday();
Robot robot = new Robot();
robot.id();
robot.model();
Pet pet = new Pet();
pet.name();
pet.birthday();
BirthdayCheck(pet.Birthday, human.Birthday); // birthdaycheck is method of the program class, hence does not need to be invoked with a new program object.
// Additionally, you need to pass an actual birthday value to compare instead of blank strings.
Console.ReadKey(); // this step ensures the console does not close after the birthday check
}
public static void BirthdayCheck(string userResponse1, string userResponse2)
{
if (userResponse1 == userResponse2)
{
Console.WriteLine("" + userResponse1);
}
else
{
Console.WriteLine("No matching birthday");
}
}
Here's an output sample of the program after the above mentioned changes:
Citizen name:
w
Citizen's age:
12
Citizen's id:
1
Citizen's birthday:
10/10/1990
Enter Robot Id:
2
Enter Robot Model:
r2d2
Enter pet name:
p2v2
Enter pet birthday:
11/11/1991
No matching birthday
userResponse1 and userResponse2 are out of scope from the BirthdayCheck method. you need to either pass in references to the human/pet objects(like human.userResponse2 == pet.userResponse1) or pass the birthdays themselves in to compare.
Is there a reason why you made this so complicated?
You made 3 classes and 3 interfaces and how do you expect them to work together?
You use Console.WriteLine(); without variables.
Does your code need to make sense? If its just for practice, you should
slow down and try something more simple, like 2 classes and then compare,
then 2 classes and 1 interface and then compare...
you mean
public string BirthdayCheck()
{
you were missing () from the method declaration
Related
I’m trying to create a program which has multiple classes. In the program.cs I have inserted example text but whenever I run the program it doesn’t output the text it only outputs the name of the program and the class files, e.g. Testprogram.Customer
And I can’t workout why.
The Bank code is:
namespace CashMachine
{
class Bank
{
private string bankname;
private string location;
public Bank(string name, string location)
{
this.bankname = bankname;
this.location = location;
}
public string Getname()
{
return this.bankname;
}
public string Getlocation()
{
return this.location;
}
}
}
The program cs code is:
namespace CashMachine
{
class Program
{
static void Main(string[] args)
{
Bank b = new Bank("NatWest", "London");
{
Console.WriteLine(b);
}
Console.WriteLine();
Console.WriteLine();
Customer c = new Customer("Joe", "UK", "joelndn", "May");
Console.WriteLine(c);
Console.ReadKey();
}
}
}
If we take the first example, of Bank, you have:
Bank b = new Bank("NatWest", "London");
Console.WriteLine(b);
Now; the system doesn't automatically know what you want to write about the Bank, but everything that subclasses object has a public virtual string ToString() method, for creating a text representation of a type, so: this is what gets called. The default implementation of ToString() is to output the type name, but if you want to do something more interesting: tell it what you want.
I would suggest:
public override string ToString()
{
return Getname();
}
You can do something similar with Customer to tell it what the default output would be for that.
Alternatively: just be explicit in your output code, i.e.
Console.WriteLine(b.Getname());
Finally, you might want to consider properties instead of methods like Getname, for example (using modern C# syntax):
class Bank
{
public string Name { get; }
public string Location { get; }
public Bank(string name, string location)
{
Name = name;
Location = location;
}
public override string ToString() => Name;
}
Summary of the problem
Actually I just want to use normal inheritance functionality.
The catch is, that some of my methods are static, so they cannot access the inherited properties like normal.
Furthermore, I cannot pass anything to the static methods (like the instance of the object), because they are called by "external triggers".
On the other side I don't need multiple instances, meaning something like a singleton would be fine.
Let me explain you my situation step by step:
(Or just jump to the first code sample to see the MCV example)
Requirement 1 - Static methods accessing members
I'm using the library Harmony for patching methods of an existing Assembly.
The patching methods must be static and are called by the "hooks" of the library.
I add new player upgrades to a game. For each upgrade I want to patch I create a class with members, like name, description, image ...
One Upgrade must be only patched once, so the solution here would be making everthing static.
But ...
Requirement 2 - Inheritance
Because these upgrades share a lot of common members and methods, I make a BaseUpgrade class and derive from it.
Each specific implementation can now assign their values to the common fields like name, description ... and inherit the rest (the methods using the members).
Yet the members aren't accessible from the static patching methods anymore. For that I can use Singletons.
I want to inherit all the Singleton stuff too, making it generic. This way only the base class has all the Singeton code.
One approach would be this solution: https://stackoverflow.com/a/16865465
However ...
Requirement 3 - Having a Collection of the base class
I need to have collections of the base class and use them in dictionaries (both as key and value). But that doesn't seem to work with generic classes.
I found Collection of generic types, but I'm stuck. I don't know if incorporating this will actually work. At least it would complicate things even more.
Would that work? Is there maybe a much more simple approach to my problem?
MCV Example of the Basic Scenario
using System;
using System.Collections.Generic;
namespace Using_Singleton
{
// This is the version trying to incorperate the inheritable singleton
class Base<T> where T : Base<T>, new()
{
#region Singleton stuff
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
_instance = new T();
return _instance;
}
set => _instance = value;
}
#endregion
public string name; // Should be accessible by the derived class' static methods
public string desc;
protected Base()
{
name = "Base";
}
public void printName()
{
Console.WriteLine(name);
}
}
class FirstChild : Base<FirstChild>
{
public int number; // Should be accessible by the class' static methods
public FirstChild()
{
name = "The first child";
number = 7;
}
public static void StaticMethod_FirstChild()
{
Console.WriteLine("StaticMethod_FirstChild: I can access all member variables! :-)");
Console.WriteLine("Name: " + Instance.name + ", Number: " + Instance.number); // This is now working
}
}
class SecondChild : Base<SecondChild>
{
public float myfloat;
public SecondChild()
{
name = "The second child";
myfloat = 0.3f;
}
public static void StaticMethod_SecondChild()
{
Console.WriteLine("StaticMethod_SecondChild: I can access all member variables! :-)");
Console.WriteLine("Name 2x: " + Instance.name + " " + Instance.name); // This is now working
}
}
class Manager // Manages instances/singletons which derive from "Base" by using a collection of the Base class
{
//Dictionary<string, Base> itemDict; // ******* This is now broken
public Manager()
{
//itemDict = new Dictionary<string, Base>();
//Base addItem;
//addItem = new FirstChild();
//itemDict.Add(addItem.GetType().Name, addItem);
//addItem = new SecondChild();
//itemDict.Add(addItem.GetType().Name, addItem);
// Simulating the external call of one static method
SecondChild.StaticMethod_SecondChild();
Console.WriteLine();
}
public void DoSomething()
{
//foreach (var item in itemDict)
//{
// item.Value.printName();
//}
}
}
class Program
{
static void Main(string[] args)
{
Manager manager = new Manager();
manager.DoSomething();
Console.ReadLine();
}
}
}
Example using Inheritable Singletons
using System;
using System.Collections.Generic;
namespace Using_Singleton
{
// This is the version trying to incorperate the inheritable singleton
class Base<T> where T : Base<T>, new()
{
#region Singleton stuff
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
_instance = new T();
return _instance;
}
set => _instance = value;
}
#endregion
public string name; // Should be accessible by the derived class' static methods
public string desc;
protected Base()
{
name = "Base";
}
public void printName()
{
Console.WriteLine(name);
}
}
class FirstChild : Base<FirstChild>
{
public int number; // Should be accessible by the class' static methods
public FirstChild()
{
name = "The first child";
number = 7;
}
public static void StaticMethod_FirstChild()
{
Console.WriteLine("StaticMethod_FirstChild: I can access all member variables! :-)");
Console.WriteLine("Name: " + Instance.name + ", Number: " + Instance.number); // This is now working
}
}
class SecondChild : Base<SecondChild>
{
public float myfloat;
public SecondChild()
{
name = "The second child";
myfloat = 0.3f;
}
public static void StaticMethod_SecondChild()
{
Console.WriteLine("StaticMethod_SecondChild: I can access all member variables! :-)");
Console.WriteLine("Name 2x: " + Instance.name + " " + Instance.name); // This is now working
}
}
class Manager // Manages instances/singletons which derive from "Base" by using a collection of the Base class
{
//Dictionary<string, Base> itemDict; // ******* This is now broken
public Manager()
{
//itemDict = new Dictionary<string, Base>();
//Base addItem;
//addItem = new FirstChild();
//itemDict.Add(addItem.GetType().Name, addItem);
//addItem = new SecondChild();
//itemDict.Add(addItem.GetType().Name, addItem);
// Simulating the external call of one static method
SecondChild.StaticMethod_SecondChild();
Console.WriteLine();
}
public void DoSomething()
{
//foreach (var item in itemDict)
//{
// item.Value.printName();
//}
}
}
class Program
{
static void Main(string[] args)
{
Manager manager = new Manager();
manager.DoSomething();
Console.ReadLine();
}
}
}
After adding Inheritable Singletons to the small example I tried adding support for a generic collection, as suggested by Jon Saunders.
Basically making either an interface or class "above" the singleton class (the singleton class inherits it) and using this for the collection or in method parameters.
In this new non-generic class I've put all fields and methods. The constructors of the top non-generic class and the generic class are protected, so they cannot be instantiated.
Working solution
using System;
using System.Collections.Generic;
namespace Using_Singleton_And_GenericCollection
{
// This is the version trying to incorperate the inheritable singleton and a generic collection
abstract class NonGenericBase // Adding this (class or interface) make the use of collections possible.
{
public string name;
public string desc;
public void printName()
{
Console.WriteLine("\t" + name);
}
protected NonGenericBase() { }
}
class Base<T> : NonGenericBase where T : Base<T>, new()
{
#region Singleton stuff
protected static T _instance;
public static T Instance
{
get
{
if (_instance == null)
_instance = new T();
return _instance;
}
set => _instance = value;
}
#endregion
//public string name; // Moved to parent
//public string desc;
protected Base()
{
name = "Base";
}
}
class FirstChild : Base<FirstChild>
{
public int number; // Should be accessible by the class' static methods
public FirstChild()
{
name = "The first child";
number = 7;
}
public static void StaticMethod_FirstChild()
{
Console.WriteLine("\tStaticMethod_FirstChild: I can access all member variables! :-)");
Console.WriteLine("\tName: " + Instance.name + ", Number: " + Instance.number); // This is now working
}
}
class SecondChild : Base<SecondChild>
{
public float myfloat;
public SecondChild()
{
name = "The second child";
myfloat = 0.3f;
}
public static void StaticMethod_SecondChild()
{
Console.WriteLine("\tStaticMethod_SecondChild: I can access all member variables! :-)");
Console.WriteLine("\tName 2x: " + Instance.name + ", " + Instance.name); // This is now working
}
}
class Manager // Manages instances/singletons which derive from "Base" by using a collection of the Base class
{
public Dictionary<string, NonGenericBase> itemDict;
public Manager()
{
itemDict = new Dictionary<string, NonGenericBase>();
NonGenericBase addItem;
addItem = FirstChild.Instance;
itemDict.Add(addItem.GetType().Name, addItem);
addItem = SecondChild.Instance;
itemDict.Add(addItem.GetType().Name, addItem);
}
public void DoSomething()
{
foreach (var item in itemDict)
{
item.Value.printName();
}
Console.WriteLine();
}
}
class Program
{
static void Main(string[] args)
{
var sec = new SecondChild();
Console.WriteLine("Access Singletons");
Manager manager = new Manager();
manager.DoSomething();
Console.WriteLine("Change Singletons");
manager.itemDict[nameof(FirstChild)].name = "first name changed";
SecondChild.Instance.name = "second name changed too";
manager.DoSomething();
Console.WriteLine("Create and change a non-Singleton instance of FirstChild");
var initItem = new FirstChild();
initItem.printName();
initItem.name = "Non-Singleton name changed";
initItem.printName();
Console.WriteLine();
Console.WriteLine("Access Singletons");
manager.DoSomething();
Console.WriteLine("Call static method of FirstChild");
FirstChild.StaticMethod_FirstChild(); //Simulating the external call of one static method
Console.WriteLine();
Console.ReadKey();
}
}
}
Output
Access Singletons
The first child
The second child
Change Singletons
first name changed
second name changed too
Create and change a non-Singleton instance of FirstChild
The first child
Non-Singleton name changed
Access Singletons
first name changed
second name changed too
Call static method of FirstChild
StaticMethod_FirstChild: I can access all member variables! :-)
Name: first name changed, Number: 7
Caveat
Because of the "new()" here
class Base<T> : NonGenericBase where T : Base<T>, new()
the constructors of the specific sub classes need to be public. This means that the Singletons aren't enforced, but "just" an option (see the output for an example).
BTownTKD states that in his answer he states that fact and links to his attempt to solve this via reflection an manually invoking private constructors here: Singleton.cs
Conclusion
Thanks to doing the MCV example for this question and trying it again with a greatly reduced complexity I've found the solution myself.
So this questioning process here and improving my initial post helped me with it. :-)
I have two classes, Dog and Cat
class Dog
{
public void speak() {
System.out.println("Woof!");
}
}
class Cat
{
public void speak() {
System.out.print("Meow!");
}
}
In my main, I take the name as String, either "Cat", or "Dog".
public static void main(String [] args)
{
Scanner sc = new Scanner(System.in);
String name = sc.next();
Class<?> cls = Class.forName(name);
Object object = cls.newInstance();
}
Can i do this in C#??
Line by line it would be:
public static void Main(string[] args)
{
string name = Console.ReadLine();
// The second true will ignore case
var cls = Type.GetType("Animals." + name, true, true);
var #object = Activator.CreateInstance(cls);
}
with the various animals like:
namespace Animals
{
public class Dog
{
public void speak()
{
Console.WriteLine("Woof!");
}
}
public class Cat
{
public void speak()
{
Console.WriteLine("Meow!");
}
}
}
I've added a namespace to make it a "more complete" example: in .NET you can have your code *outside" any namespace, but normally you'll use a namespace. I'm prepending it to the name of the class obtained from the console ("Animals." + name).
Note that this code is quite useless, because without a base interface/class, you can't easily make them speak() (you can go full reflection/dynamic from this point onward to do it but it is "bad")
Bad way with dynanic:
dynamic #object = Activator.CreateInstance(cls);
#object.speak();
(note that I'm not supporting what you are doing, it is bad in multiple ways)
I have two classes, one which is to contain a list (Student) and the other is a menu program which uses it (Program).
When I return the list from the Student Class, it is returningSystem.Collections.Generic.List'1[2015Assignment.StudentClass].
Why is the data not being returned?
It is built in the Student Class like this:
namespace 2015Assignment
{
class StudentClass
{
private string StoredStudentName;
public List<StudentClass> GetName()
{
/*----------------------------------------------------------------------*
* Hard Programming the list of students *
*----------------------------------------------------------------------*/
List<StudentClass> ListOfStudents = new List<StudentClass>();
ListOfStudents.Add(new StudentClass("Jane"));
ListOfStudents.Add(new StudentClass("Alex"));
ListOfStudents.Add(new StudentClass("Mike"));
ListOfStudents.Add(new StudentClass("James"));
ListOfStudents.Add(new StudentClass("Julia"));
return ListOfStudents;
}
public StudentClass(string StudentName)
{
StoredStudentName = StudentName;
}
}
}
And called/written to the console in the Program Class like this:
StudentClass studentClass = new StudentClass("");
static void Main()
{
Program program = new Program();
List<StudentClass> ListOfStudents = program.studentClass.GetName().ToList();
ListOfStudents.ForEach(i => Console.WriteLine("{0}", i.GetName()));
Console.WriteLine("\r\nPress any key to continue...");
Console.ReadKey();
}
#Maxim Goncharuk is absolutely correct regarding why you see System.Collections.Generic.List'1[2015Assignment.StudentClass] printed in the console. Your GetName() method returns List<StudentClass> and you see its string representation.
I would rewrite your StudentClass as:
internal class Student
{
public string Name { get; set; }
public Student(string name)
{
this.Name = name;
}
public static List<Student> GenerateStudents()
{
var students= new List<Student>();
students.Add(new Student("Jane"));
students.Add(new Student("Alex"));
students.Add(new Student("Mike"));
students.Add(new Student("James"));
students.Add(new Student("Julia"));
return students;
}
}
Several reasons:
You should not include type information into your names. Thus, StudentClass should be just Student
GetName() method name is not a very good name for something that generates data. Confusing.
There is no need for private field for name in your case. Just use a simple public property. If you want to prevent outside code from changing Name, just make the set accessor private: public string Name { get; private set; }
There is no need for a Student instance to generate data. Make sense to make this method static
I would also rewrite your Program class as follows:
class Program
{
static void Main()
{
var students = Student.GenerateStudents();
students.ForEach(i => Console.WriteLine("{0}", i.Name));
Console.WriteLine("\r\nPress any key to continue...");
Console.ReadKey();
}
}
Reasons:
I don't see why you need to keep an instance of Student (StudentClass in your original code) as part of your Program class. Local variable fits better if you just want to write something to console
Generally, it's not a good practice to instantiate your Program class. It should serve just an entrance to your application and should be used by framework only
You call method i.GetName() which return List<StudentClass> and Console.WriteLine call ToString(), so you have System.Collections.Generic.List'1[2015Assignment.StudentClass]
Try this:
using System;
using System.Collections.Generic;
using System.Linq;
public class StudentClass
{
private string _storedStudentName;
public static List<StudentClass> GetStudents()
{
List<StudentClass> ListOfStudents = new List<StudentClass>();
ListOfStudents.Add(new StudentClass("Jane"));
ListOfStudents.Add(new StudentClass("Alex"));
ListOfStudents.Add(new StudentClass("Mike"));
ListOfStudents.Add(new StudentClass("James"));
ListOfStudents.Add(new StudentClass("Julia"));
return ListOfStudents;
}
public string Name
{
get
{
return _storedStudentName;
}
}
public StudentClass(string StudentName)
{
_storedStudentName = StudentName;
}
}
Program:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
List<StudentClass> ListOfStudents = StudentClass.GetStudents();
ListOfStudents.ForEach(i => Console.WriteLine("{0}", i.Name));
Console.WriteLine("\r\nPress any key to continue...");
Console.ReadKey();
}
}
Refactored a few things in your code. Your code actually didn't make a lot of sense (or maybe its just me)
//namespace can not start with a number
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//You need to define the list in your host program, not inside the class itself
List<StudentClass> ListOfStudents = new List<StudentClass>();
ListOfStudents.Add(new StudentClass("Jane"));
ListOfStudents.Add(new StudentClass("Alex"));
ListOfStudents.Add(new StudentClass("Mike"));
ListOfStudents.Add(new StudentClass("James"));
ListOfStudents.Add(new StudentClass("Julia"));
ListOfStudents.ForEach(i => Console.WriteLine("{0}", i.GetName()));
Console.WriteLine("\r\nPress any key to continue...");
Console.ReadKey();
}
}
//changed the class to public so you can access it.
public class StudentClass
{
private string _storedStudentName;
public string GetName()
{
return _storedStudentName;
}
public StudentClass(string studentName)
{
_storedStudentName = studentName;
}
}
}
I am a very very very basic programmer just starting off. I have followed a few tutorials and I am now trying to branch out into my own stuff but I keep getting the same Error that I cant rectify.
static void Main(string[] args)
{
///Call Method
OutWelcome();
///Return the name from getname method
Inputname = getname();
Console.WriteLine(" {0}", Inputname);
}
public static void OutWelcome()
{
Console.WriteLine("Welcome");
}
public static string getname()
{
///Declare Variable
string Inputname;
///Prompt User
Console.WriteLine("Enter your Name: ");
///Get name from user keyboard
Inputname = Console.ReadLine();
///Returns name
return Inputname;
}
}
I keep getting the following error "The name 'Inputname' does not exist in the current context. Line 18, 17 and 19
I know the answer will be so simple its n00b worthy, but I am new and we all have to start somewhere.
Thank you in advance
Sean
Please use the below code :
static void Main(string[] args)
{
///Call Method
OutWelcome();
///Return the name from getname method
string Inputname = getname();
Console.WriteLine(" {0}", Inputname);
}