Cant call a method from another class. c# [duplicate] - c#

This question already has answers here:
How to fix "No overload for method ' ' takes 0 arguments"?
(5 answers)
Closed 5 years ago.
Hello im trying to call a method in a different class so when the user selects the button 1 it will call the
It says no overload for method myMethod takes 0 arguments
using System;
namespace crap
{
class firstClass
{
public static void Main (string[] args)
{
int choice = 0;
while (choice != 1 || choice != 2) {
Console.WriteLine ("Press 1 for choice 1 or 2 for choice for choice 2");
choice = Convert.ToInt32 (Console.ReadLine ());
if (choice == 1) {
crap.secondClass.myMethod();
}
if (choice == 2) {
}
}
}
}
public class secondClass{
public static void myMethod(int later, int later2)
{
Console.WriteLine("You chose option 1");
}
}
}

using System;
namespace crap
{
class firstClass
{
public static void Main (string[] args)
{
int choice = 0;
while (choice != 1 && choice != 2)
{
Console.WriteLine ("Press 1 for choice 1 or 2 for choice for choice 2");
choice = Convert.ToInt32 (Console.ReadLine ());
if (choice == 1) {
crap.secondClass.myMethod();
}
if (choice == 2) {
}
}
}
}
public class secondClass{
public static void myMethod()
{
Console.WriteLine("You chose option 1");
}
}
}

Related

How to set default capacity for lists

So I tried making a todo list app making use of for loops and nested if statements. I created a function for adding tasks deleting and showing the whole list, but when I run the code I only get to input a task once even though I set the list capacity to what the user wants.
This is my code and what I've tried so far:
namespace mycsharpproject1
{
class Program
{
static void Main(string[] args)
{
List<string> todo = new List<string>();
void addt()
{
Console.WriteLine("enter task to be add");
todo.Add(Console.ReadLine());
}
void removet()
{
Console.WriteLine("enter task to be removed");
todo.Remove(Console.ReadLine());
}
void showt()
{
Console.WriteLine(todo);
}
string user_input = Console.ReadLine();
if (user_input == "r")
{
if (todo.Count == 0)
{
Console.WriteLine("you have no tasks in your list");
}
else
{
removet();
}
}
if (user_input == "a")
{
int i= Convert.ToInt32(Console.ReadLine());
if (i == todo.Capacity)
{
addt();
}
}
if (user_input == "s")
{
showt();
}
Console.ReadKey();
}
}
}
Modified your code a little bit. It's because there's no loop in your code, it only runs once. And the last like Console.ReadKey just reads an input and exits.
And the list doesn't need a capacity to be set if you exactly need that amount of item in yoru list. So, try this one.
class Program
{
static List<string> todo = null;
static void Main(string[] args)
{
todo = new List<string>();
while (true)
{
string user_input = Console.ReadLine();
if (user_input == "r")
{
if (todo.Count == 0)
{
Console.WriteLine("you have no tasks in your list");
}
else
{
removet();
}
}
if (user_input == "a")
{
addt();
}
if (user_input == "s")
{
showt();
}
}
}
static void addt()
{
Console.WriteLine("enter task to be add");
todo.Add(Console.ReadLine());
}
static void removet()
{
Console.WriteLine("enter task to be removed");
todo.Remove(Console.ReadLine());
}
static void showt()
{
todo.ForEach(q => Console.WriteLine(q));
}
}

Access into global variable by Console.Readline() in C#

I'm trying to improve my program for Fibonacci numbers using of memoization:
public class MyGlobals
{
public long TotNum { get; set; }
public long[] MyNumbers { get; set; }
public void GetParam()
{
Console.Write("n = ");
this.TotNum = long.Parse(Console.ReadLine());
this.MyNumbers = new long[this.TotNum + 1];
// set all numbers to -1
for (int i = 0; i < this.MyNumbers.Length; i++)
{
this.MyNumbers[i] = -1;
}
}
}
class Program
{
static void Main(string[] args)
{
MyGlobals globVariable = new MyGlobals();
globVariable.GetParam();
long n = globVariable.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, Fibonacci(n));
Console.ReadKey();
}
static long Fibonacci(long n)
{
MyGlobals globVariable = new MyGlobals();
if (n <= 1)
{
return 1;
}
if (globVariable.MyNumbers[n] != -1)
{
return globVariable.MyNumbers[n];
}
else
{
globVariable.MyNumbers[n] = Fibonacci(n - 1) + Fibonacci(n - 2);
}
return globVariable.MyNumbers[n];
}
}
I'm trying to do something like feed an array by -1 in MyGlobals class for further using MyNumbers array in Fibonacci static method.
Until line where I'm starting to call recursive fibonacci method it holds MyNumbers array in memory. But in Fibonacci method, when I create new instance of MyGlobals class for calling MyNumbers array is this array empty... What I'm doing wrong. Can you anybody help me on this, please. Thank you very much in forward.
Declare globVariable as a static member of the Program class like so:
class Program
{
static MyGlobals globVariable = new MyGlobals();
static void Main(string[] args)
{
globVariable.GetParam();
long n = globVariable.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, Fibonacci(n));
Console.ReadKey();
}
static long Fibonacci(long n)
{
if (n <= 1)
{
return 1;
}
if (globVariable.MyNumbers[n] != -1)
{
return globVariable.MyNumbers[n];
}
else
{
globVariable.MyNumbers[n] = Fibonacci(n - 1) + Fibonacci(n - 2);
}
return globVariable.MyNumbers[n];
}
}
There is no such thing as global variables in C#. The problem you're having relates to instances of nonstatic classes.
You effectively have three separate units in your code:
One class that asks for input, holds this input and holds an array of result variables (MyGlobals). This is in fact way too much for a single class and should ultimately be split up.
One method that calculates Fibonacci numbers and stores them into the previous class (Fibonacci).
A Program class and Main() method which host your console application.
Now your problem is that you don't know how to access the array of inputs stored in 1 from method 2. There are various ways to solve that, each with their own cons and pros. The most obvious one is to pass a reference.
But before that, clean up your code: give classes and methods meaningful names, and extract logic into separate classes.
Here you'll remain with three classes:
public class FibonacciInput
{
public void GetParam()
{
// Your "MyGlobals" logic
}
}
Then the calculation logic:
public class FibonacciCalculator
{
public long Fibonacci(long index, long[] range)
{
// Your "Fibonacci()" logic
}
}
And the program:
class Program
{
static void Main(string[] args)
{
FibonacciInput input = new FibonacciInput();
FibonacciCalculator calculator = new FibonacciCalculator();
input.GetParam();
long n = input.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, calculator.Fibonacci(n, input.MyNumbers));
Console.ReadKey();
}
}
Now your calculator doesn't know anything about your input, and the need for "global variables" goes away.
The point is that the Fibonacci() method needs two things: the index (the Nth Fibonacci number it should calculate) and an array to work with (which you initialized on beforehand).
So by calling calculator.Fibonacci(n, input.MyNumbers), you solve all problems at once.
Well, may be it's not really answers your question but i'd refactor your code dividing it to logical parts where each part is only responsible for one thing :
UI
Global variables
Class that knows how to work with fibo sequence
Program (entry point)
Refactored code may look something among the lines of :
// Globals should be static
public static class MyGlobals
{
public static long TotNum { get; private set; }
public static long[] MyNumbers { get; private set; }
public static void SetNum(long num)
{
TotNum = num;
MyNumbers = new long[TotNum + 1];
}
}
// interacts with UI
public static class UIHelper
{
public static long GetParam()
{
Console.Write("n = ");
var number = long.Parse(Console.ReadLine());
return number;
}
}
// Knows how to calc fibo
static class Fibo
{
static long Calc(long[] nums, long n)
{
... calc fibonacci logic
}
}
class Program
{
static void Main(string[] args)
{
// now we can use them all
// first lets get value from console
var num = UIHelper.GetParam();
// set global variables with this value
MyGlobals.SetNum(num);
// output result :
Console.WriteLine("Fib ({0}) = {1}", n, Fibo.Calc(MyGlobals.MyNumbers, MyGlobals.TotalNum));
Console.ReadKey();
}
}
P.S.
Whether to send global values as parameters to Fibo.Calc() method or to access them directly from inside of it it's up to you. I vote for first option because it makes it easier to test this method by passing mock data.

C# Accessing a list from multiple methods

I am looking to access a list from different methods in the same class.Is there an easier way to access the movieTitle list without making a new list for each method? Do I have to make a reference to the list in every method? or should I put them all into a separate class all together? My overall goal is to have a option menu that gets input from the user and depending on the input calls a method to list all movies, add a movie to the list, and pick a random movie from the list.
class Program
{
static void Main(string[] args)
{
optionMenu();
Console.Read();
}
static void optionMenu()
{
Console.Write("(a)LIST MOVIES|(b)ADD Movie|(c)RANDOM MOVIE");
string ui = Console.ReadLine();
if (ui == "a") { printNames(); }
else if (ui == "b") { addMovie(); }
else if (ui == "b") { randomPickMovie(); }
else { optionMenu(); }
}
static void printNames()
{
List<string> movieTitles = new List<string>();
/*list.....
/ movieTitles.Add("Jurassic Park");
/..........
/..........
*/..........
Console.WriteLine("Movies in your list...");
for (int i = 0; i < movieTitles.Count;i++)
{
Console.WriteLine("\t-" + movieTitles[i]);
}
}
static void addMovie()
{
Console.WriteLine("Enter a title:");
string newTitle = Console.ReadLine();
//I can't say...
//movieTitles.Add(newTitle);
//...? do I need to make an instance of the list?
}
static void randomPickMovie()
{
Random r = new Random();
int random = r.Next();
Console.WriteLine(movieTitle[random]);
//same here. How do I access the movie titles in the printName() method so
//I can randomly pick a movie from the list?
}
}
Below is one way make the movie list shared. This declares and initializes the list as a static member of the class (instead of a local variable in the methods).
This approach works well for simple programs, but having global state in a large program can be problematic because it becomes difficult to see which methods affect which global state so bugs can easily creep in. See below for another approach.
class Program
{
static void Main(string[] args)
{
...
}
static List<string> movieTitles = new List<string>();
static void optionMenu()
{
...
}
static void printNames()
{
Console.WriteLine("Movies in your list...");
for (int i = 0; i < movieTitles.Count;i++)
{
Console.WriteLine("\t-" + movieTitles[i]);
}
}
static void addMovie()
{
movieTitles.Add(newTitle);
}
static void randomPickMovie()
{
...
}
}
Another approach is to pass the data from one method to another. This makes it more obvious to see what methods use the movieList. It also allows us to specify additional restrictions, e.g. you can see that printNames only needs a read-only version of the list so you know that printNames can't modify the list. This approach is a little more work but it's a good habit to get into because it reduces bugs in the long term.
class Program
{
static void Main(string[] args)
{
...
}
static void optionMenu()
{
List<string> movieTitles = new List<string>();
string ui = Console.ReadLine();
if (ui == "a") { printNames(movieTitles); }
else if (ui == "b") { addMovie(movieTitles); }
else if (ui == "b") { randomPickMovie(movieTitles); }
else { optionMenu(); }
}
static void printNames(IReadOnlyList<string> movieTitles)
{
Console.WriteLine("Movies in your list...");
for (int i = 0; i < movieTitles.Count;i++)
{
Console.WriteLine("\t-" + movieTitles[i]);
}
}
static void addMovie(List<string> movieTitles)
{
movieTitles.Add(newTitle);
}
static void randomPickMovie(List<string> movieTitles)
{
...
}
}
See https://stackoverflow.com/questions/13295319/instance-field-vs-passing-method-parameter for another user's point of view on which approach is better.
as for me, I prefer doing it this way.
class Program
{
static void Main(string[] args)
{
Movie movie = new Movie();
int x = 0;
while (x < 1)
{
movie.optionMenu(); Console.Write("Do you want to exit?");
string response = Console.ReadLine();
if (response == "Y") { x = 1; }
}
Console.Read();
}
}
class Movie
{
public List<string> movieTitles { get; set; }
public Movie()
{
movieTitles = new List<string>();
}
public void optionMenu()
{
Console.Write("(a)LIST MOVIES|(b)ADD Movie|(c)RANDOM MOVIE");
string ui = Console.ReadLine();
if (ui == "a") { printNames(); }
else if (ui == "b") { addMovie(); }
else if (ui == "c") { randomPickMovie(); }
else { optionMenu(); }
}
public void printNames()
{
Console.WriteLine("Movies in your list...");
for (int i = 0; i < movieTitles.Count; i++)
{
Console.WriteLine("\t-" + movieTitles[i]);
}
}
public void addMovie()
{
Console.WriteLine("Enter a title:");
string newTitle = Console.ReadLine();
if (newTitle != "")
{
movieTitles.Add(newTitle);
Console.WriteLine("New movie successfully added!");
}
else
{
Console.WriteLine("Cannot add empty movie. Add movie failed.");
}
}
public void randomPickMovie()
{
if (movieTitles.Count != 0)
{
Random r = new Random();
int random = r.Next(0, movieTitles.Count - 1);
Console.WriteLine(movieTitles[random]);
}
else { Console.WriteLine("Movie list is empty."); }
}
}
Answer for all your questions is create MovieTitles property of type List<string> and access it like this:
class Program
{
static void Main(string[] args)
{
optionMenu();
Console.Read();
}
static List<string> movieTitles;
static List<string> MovieTitles
{
get
{
if (movieTitles == null)
CreateMoviesList();
return movieTitles;
}
}
static void CreateMoviesList()
{
movieTitles = new List<string>();
/*list.....
/ movieTitles.Add("Jurassic Park");
/..........
/..........
*/
}
static void optionMenu()
{
Console.Write("(a)LIST MOVIES|(b)ADD Movie|(c)RANDOM MOVIE");
string ui = Console.ReadLine();
if (ui == "a") { printNames(); }
else if (ui == "b") { addMovie(); }
else if (ui == "b") { randomPickMovie(); }
else { optionMenu(); }
}
static void printNames()
{
Console.WriteLine("Movies in your list...");
for (int i = 0; i < MovieTitles.Count; i++)
{
Console.WriteLine("\t-" + movieTitles[i]);
}
}
static void addMovie()
{
Console.WriteLine("Enter a title:");
string newTitle = Console.ReadLine();
MovieTitles.Add(newTitle);
}
static void randomPickMovie()
{
Random r = new Random();
int random = r.Next();
Console.WriteLine(MovieTitles[random]);
}
}
CreateMoviesList() create list of movies only once and can be use to print movies, randon pick and add movies later on.

How value of baseclass variable is deffering from derived class's variable? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
in c# program below value of baseclass deffers from derived class same variable which is inherited, baseclass is abstract, but variable is declared in baseclass only.
Here is the C# console program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApplication
{
class MainClass
{
abstract class CBaseClass
{
public int iCount;
public CBaseClass()
{
Console.WriteLine("CBaseClass created");
iCount = 30;
}
public virtual void Add() { iCount += 20; }
public virtual void Add(int iAdd) { iCount += iAdd; }
public void Subtract() { iCount -= 20; }
public abstract void Subtract(int iSubtract);
public override string ToString()
{
return base.ToString() + ".. Method of BaseClass";
}
~CBaseClass() { Console.WriteLine("CBaseClass deleted"); }
};
class CDerivedClass : CBaseClass
{
public CDerivedClass()
{
Console.WriteLine(" CDerivedClass created.");
iCount = 50;
}
public override void Add()
{
iCount += 20;
}
public void Add(int iAdd)
{
iCount += iAdd;
}
public void Subtract()
{
iCount -= 40;
}
public sealed override void Subtract(int iSubtract)
{
iCount -= 10;
}
~CDerivedClass() { Console.WriteLine("CDerivedClass deleted \n"); }
};
static void Main(string[] args)
{
CDerivedClass deriveObject = new CDerivedClass();
CBaseClass basePointer = new CDerivedClass();
CDerivedClass notUsed;
Console.WriteLine("1:" + deriveObject.iCount);
deriveObject.Add();
Console.WriteLine("2:" + deriveObject.iCount);
basePointer.Add(30);
Console.WriteLine("3:" + basePointer.iCount);
basePointer.Subtract();
Console.WriteLine("4:" + basePointer.iCount);
basePointer.Subtract(20);
Console.WriteLine("5:" + basePointer.iCount);
Console.WriteLine("6:{0}",basePointer);
Console.ReadLine();
}
}
}
Here is the output:
CBaseClass created
CDerivedClass created.
CBaseClass created
CDerivedClass created.
1:50
2:70
3:80
4:60
5:50
6:TestApplication.MainClass+CDerivedClass..Method of BaseClass
here in above output i can't understand .. when we call base class method add(30).
basePointer.Add(30); When we call this method... before that value of iCount is 70. but after this its becoming 50. how ?
i expect output of 3: 100
Let's step through the code line-by-line to see what's happening to each object's iCount field:
CDerivedClass deriveObject = new CDerivedClass();
CBaseClass basePointer = new CDerivedClass();
CDerivedClass notUsed;
// deriveObject.iCount == 50
// basePointer.iCount == 50
deriveObject and basePointer both have iCount initialized to 50 because of the way constructors are called on derived objects in C#.
In this case:
The base class constructor is called, first setting the `iCount` value to 30 and printing the base class message.
Next, the subclass constructor is called, setting `iCount` to 50 (and overwriting the 30).
Console.WriteLine("1:" + deriveObject.iCount); // 1:50
deriveObject.Add();
// CDerivedClass.Add is called on deriveObject
// deriveObject.iCount == 70
Console.WriteLine("2:" + deriveObject.iCount); // 2:70
basePointer.Add(30);
// CDerivedClass.Add is called on basePointer
// basePointer.iCount == 80
Console.WriteLine("3:" + basePointer.iCount); // 3:80
basePointer.Subtract();
// CBaseClass.Subtract is called on basePointer, since `CDerivedClass` does not
// override the Subtract method.
// basePointer.iCount == 60
Console.WriteLine("4:" + basePointer.iCount); // 4:60
basePointer.Subtract(20);
// CDerivedClass.Subtract is called on basePointer. *Note* that this subtracts 10.
// basePointer.iCount == 50
Console.WriteLine("5:" + basePointer.iCount); // 5:50
Console.WriteLine("6:{0}",basePointer);
Console.ReadLine();
deriveObject and basePointer reference two different instances of CDerivedClass.
The only tricky part is with the call to basePointer.Subtract() ("3"). Since CDerivedClass does not mark its Subtract method as "override", the base class' method is called.

Variables reset to zero when I call a method

I want choice == 1 to only be able to be selected five times, so I initialized a variable firstClass = 0, then set up a do-while for firstClass < 5. I included firstClass++ in my do-while to act as a counter. However, I think firstClass is re-initializing every time I call the method CheckIn(). How can I prevent this from happening? Thanks in advance.
using System;
namespace Assignment7
{
class Plane
{
public static void Main(string[] args)
{
Console.WriteLine("Welcome to the Airline Reservation System.");
Console.WriteLine("Where would you like to sit?\n");
Console.WriteLine("Enter 1 for First Class.");
Console.WriteLine("Enter 2 for Economy.");
CheckIn();
}
public static void CheckIn()
{
int choice = Convert.ToInt32(Console.ReadLine());
int firstClass = 0;
int economy = 0;
if (choice == 1)
{
do
{
Console.WriteLine("You have chosen a First Class seat.");
firstClass++;
CheckIn();
} while (firstClass < 5);
}
else if (choice == 2)
{
do
{
Console.WriteLine("You have chosen an Economy seat.");
economy++;
CheckIn();
} while (economy < 5);
}
else
{
Console.WriteLine("That does not compute.");
CheckIn();
}
}
}
}
That is entirely normal. If you want the variable to exist outside the method, you must declare it outside a method, as a "field". Simply move the:
int firstClass = 0;
outside the method, adding the static modifier (in this case):
static int firstClass = 0;
Note also that this by itself is not thread-safe; if threading is an issue (for example, ASP.NET) then use int newValue = Interlocked.Increment(ref firstClass);. I only mention this because in the general case static data should consider threading, but I suspect it isn't an issue in your case (a console exe).
The firstClass variable is method scoped. Every time the method is called the variable is reinitialized. To have firstClass become an ongoing counter it needs to be outside the method, within the class.
You need to take any exit condition out of your method and put it outside, either by making a new method or putting it in the one that's calling it already.
For example you could do something like:
using System;
namespace Assignment7
{
class Plane
{
public static void Main(string[] args)
{
Console.WriteLine("Welcome to the Airline Reservation System.");
Console.WriteLine("Where would you like to sit?\n");
Console.WriteLine("Enter 1 for First Class.");
Console.WriteLine("Enter 2 for Economy.");
CheckIn(0, 0);
}
public static void CheckIn(int firstClassSeatsTaken, int economySeatsTaken)
{
int choice = Convert.ToInt32(Console.ReadLine());
if (choice == 1)
{
do
{
Console.WriteLine("You have chosen a First Class seat.");
firstClass++;
CheckIn(firstClassSeatsTaken, economySeatsTaken);
} while (firstClass < 5);
}
else if (choice == 2)
{
do
{
Console.WriteLine("You have chosen an Economy seat.");
economy++;
CheckIn(firstClassSeatsTaken, economySeatsTaken);
} while (economy < 5);
}
else
{
Console.WriteLine("That does not compute.");
CheckIn(firstClassSeatsTaken, economySeatsTaken);
}
}
}
}

Categories

Resources