|
Can someone help me please. I'm building a structure for a C# program.
When I run this program I get the error "Program does not contain a static 'Main' method suitable for an entry point".
If I add a static to the Main [pubic static void Main(stringp[ args)] then I get errors for all the calling names such as ReadHeader; ReadVerbs; etc
What do I need to change?
Brian
public class Program
{
public void Main(string[] args)
{
ReadHeader();
ReadVerbs();
ReadNouns();
ReadObjects();
ReadStartRoom();
ReadRooms();
ReadMessages();
ReadAutoActions();
ReadActions();
Console.Read();
}
public void ReadHeader()
{
Console.WriteLine("ReadHeader");
}
public void ReadVerbs()
{
Console.WriteLine("ReadVerbs");
}
public void ReadNouns()
{
Console.WriteLine("ReadNouns");
}
public void ReadObjects()
{
Console.WriteLine("ReadObjects");
}
public void ReadStartRoom()
{
Console.WriteLine("ReadStartRoom");
}
public void ReadRooms()
{
Console.WriteLine("ReadRooms");
}
public void ReadMessages()
{
Console.WriteLine("ReadMessages");
}
public void ReadAutoActions()
{
Console.WriteLine("ReadAutoActions");
}
public void ReadActions()
{
Console.WriteLine("ReadActions");
}
}
|
|
|
|
|
You declare Main:
public void Main(string[] args)
{
ReadHeader();
ReadVerbs();
ReadNouns();
ReadObjects();
ReadStartRoom();
ReadRooms();
ReadMessages();
ReadAutoActions();
ReadActions();
Console.Read();
} But it is not declared as static , just as the error message says.
When you declare a method like this:
public void MyMethod(ParameterType parameter)
{ ... } You create an instance method: which means that it needs an instance of it's containing class in order to be used.
Think about cars for a moment: what colour is your car? What colour is my car? What colour is that car - that one, over there, next to the lamppost with the cat sitting on the roof?
Those are all questions you can ask, because you are specifying which car you are referring to: Your car is green, my car is black, that car - that one, over there, next to the lamppost with the cat sitting on the roof is red. It is an Instance Question - it requires an instance of a car to be specified in order to be asked.
You can't ask "what colour is a car?" (or more accurately you can't answer that) because not all cars are the same colour.
But you can ask "how many wheels has a car?" because all cars have four wheels (if it had 2 it would be a motorbike, and three would be a trike). "How many wheels?" is a static question, because you do not need an instance of a car to ask it.
Classes and methods are the same: Instance methods need an instance in order to be used, static methods don't.
And the Main method is where your code starts executing, so it can't have an instance as nothing exists to create an instance (and of what?) before Main is called.
And that is what the error is saying: "There is no static Main method I can call to start the code running".
Add the static keyword to your Main method declaration, and the error will go away:
public static void Main(string[] args)
{
ReadHeader();
ReadVerbs();
ReadNouns();
ReadObjects();
ReadStartRoom();
ReadRooms();
ReadMessages();
ReadAutoActions();
ReadActions();
Console.Read();
}
Of course, that will produce more errors because your other methods are also instance methods, but I think you can probably start to fix them...
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
modified 14-Mar-19 4:55am.
|
|
|
|
|
Thanks for your reply Griff and thanks for explaining it to me using cars.
Before I posted my problem I had added the static word but as I got even more errors I thought that I might not be doing the correct thing in adding the static word.
It looks like I had two errors and adding the static word caused the other problem to surface.
At this stage I don't know why I'm getting errors for "An object reference is required for the non-static field, method or property.
I'm new to programming in C# so I'm trying to work out what that means. Is there some code missing that should be added to my program?
Brian
|
|
|
|
|
Think about it!
Main has to be static - it can't have an instance or it can't be called.
So Main wants to call other methods - are they static or instance?
What should they be?
public static void Main()
{
MyMethod();
} Is calling MyMethod from a static method (called Main, it this applies to all static methods)
Let's go back to cars - can you do this?
public static void AskAboutCar()
{
Color col = WhatColourIsIt();
} No - because you aren't specifying a car you can't have an answer to that question - it needs an instance of a car in order to have a colour. You could make WhatColourIsIt static and the error goes away ... but you can't return any meaningful information from the method because you still don't know which car you are referring to! You can do this:
public static void AskAboutCar()
{
Car myCar = GetMyCar();
Color col = myCar.WhatColourIsIt();
} Because you are specifying which car you are talking about. myCar contains an object reference to my car - not your car, not that car over there; just my car - so it has a colour. If I change my car, the variable myCar doesn't change, but the value it contains (the reference) changes to a different instance of a car, which may or may not be a different colour (I like black cars but Herself may want one that matches her eyes).
So you need to think about the rest of the methods you are trying to call: are they independent of any particular instance of the containing class or not (do they need a car?)
If they don't, they can be static and you can "just use them" - possibly with the class name in front of them:
public static void AskAboutCar()
{
int wheels = Car.HowManyWheels():
} If they do, then you need to create an instance, and then access the method via that:
public static void AskAboutCar()
{
Car myCar = GetMyCar();
Color col = myCar.WhatColourIsIt();
}
Bear in mind that static methods can't access any instance related items: the variables, fields, methods, properties, delegates, and events are all unavailable unless you have a specific instance to refer to.
Inside a instance method, all instance data is automatically available, either directly:
public class Car
{
public Color Color { get; set; }
public Color WhatColourIsIt()
{
return Color;
}
} or via a special word this which directly specifies the current instance:
public class Car
{
public Color Color { get; set; }
public Color WhatColourIsIt()
{
return this.Color;
}
} (But you don't need to use this unless a local variable or a method parameter "masks" the class version:
public class Car
{
private Color Color { get; set; }
public void SetColour(Color Color)
{
this.Color = Color;
}
} In "normal" code, Main builds an instance of a class, and uses that (finds my car, and does things with it), and static isn't used much at all.
Make sense?
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi Griff.
Thanks again for trying to explain it to me using cars.
At the moment it's a lot for my mind to adsorb so after reading it a few times I hope it will sink in and give me a better underrstanding.
Maybe what I need is
public static void Main(string[]args)
{
program prog = new program() // an instant
{
}
public void class prog()
{
GetHeader();
}
public class GetHeader()
{
Console.WriteLine("Get Header")l
}
I'm still a bit in the dark but I feel the more I learn then the easier it should get.
Brian
|
|
|
|
|
Not quite - for starters the names have to match!
public class program
{
public static void Main(string[]args)
{
prog p = new prog();
p.GetHeader();
...
}
}
public class prog()
{
public void GetHeader()
{
Console.WriteLine("Get Header");
}
...
}
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Upvoted, hope more people will
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
You will learn C# much faster by studying a good tutorial, rather than posting basic questions here. download .NET Book Zero, by Charles Petzold[^], it explains everything you need to know to get started quickly.
|
|
|
|
|
Thanks Richard.
I think it was you or someone that suggested this book to me about a week ago.
I have downloaded it and have started to read it.
I do try and work out what the problem might be before I put my problem on Code Project as I'm not looking for an easy fix to my problems.
While I'm not totally new to programming, having programmed in Visual Basic 6 and Python in the past I do find that C# has stricter rules, but then I'm told that C++ is even more stricter.
Brian
|
|
|
|
|
Member 14154627 wrote: I'm told that C++ is even more stricter.
Yes and no ... C++ uses pointers a lot, rather than references, and a pointer can be converted into a pointer to any type, which you can't do in C# without "special code".
Ignore C++ for the moment, and forget about pointers - Get some solid C# experience first!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Member 14154627 wrote: and have started to read it. You need to keep reading, and then read again and again. And as you go, try all the samples, even the ones that look really simple. It really is the only way to learn, and once you understand that you just need to keep practising.
|
|
|
|
|
Hi Griff.
I think I have worked it out now.
This is what I changed.
public class Program
{
public static void Main(string[] args)
{
Program prog = new Program();
prog.ReadHeader();
prog.ReadVerbs();
prog.ReadNouns();
prog.ReadObjects();
prog.ReadStartRoom();
prog.ReadRooms();
prog.ReadMessages();
prog.ReadAutoActions();
prog.ReadActions();
Console.Read();
}
public void ReadHeader()
{
Console.WriteLine("ReadHeader");
}
public void ReadVerbs()
{
Console.WriteLine("ReadVerbs");
}
public void ReadNouns()
{
Console.WriteLine("ReadNouns");
}
public void ReadObjects()
{
Console.WriteLine("ReadObjects");
}
public void ReadStartRoom()
{
Console.WriteLine("ReadStartRoom");
}
public void ReadRooms()
{
Console.WriteLine("ReadRooms");
}
public void ReadMessages()
{
Console.WriteLine("ReadMessages");
}
public void ReadAutoActions()
{
Console.WriteLine("ReadAutoActions");
}
public void ReadActions()
{
Console.WriteLine("ReadActions");
}
}
Well at least the program works for now. Hopefully I'm heading in the right direction.
Thanks for your help.
Brian
|
|
|
|
|
That'll work, but it can be improved.
But before we get to that, please do us all a favour, and start formatting your code!
It's easy to do, just highlight it and click the "code" widget above the text box.
Then this:
public class Program
{
public static void Main(string[] args)
{
Program prog = new Program();
prog.ReadHeader();
prog.ReadVerbs();
prog.ReadNouns();
prog.ReadObjects();
prog.ReadStartRoom();
Retains its formatting and engages the syntax highlighter:
public class Program
{
public static void Main(string[] args)
{
Program prog = new Program();
prog.ReadHeader();
prog.ReadVerbs();
prog.ReadNouns();
prog.ReadObjects();
prog.ReadStartRoom();
prog.ReadRooms();
prog.ReadMessages();
Now to improvements
Does Main have anything to do with your game (I assume it's a game?)?
Probably not, so leave it in it's own class, and add a new Game class:
public class Program
{
public static void Main(string[] args)
{
Game theGame = new Game();
theGame.Start();
}
public class Game
{
public void Start()
{
ReadHeader();
ReadVerbs();
ReadNouns();
ReadObjects();
ReadStartRoom();
ReadRooms();
ReadMessages();
...
}
public void ReadHeader()
{
Console.WriteLine("ReadHeader");
}
...
} Now Game can start to take care of itself, and nothing in Main or program can be affected. You can change the whole game without changing Main at all!
Now start thinking about your methods like ReadHeader. What is it supposed to do? It reads something, but it either needs to store it as part of the instance in a class level variable:
public class Game
{
private Word[] words;
public void Start()
{
... Or it needs to return a value:
public class Game
{
public void Start()
{
Word[] words = ReadWords();
...
public Word[] ReadWords()
{
...
return words;
}
... Think carefully about the data your program will use, and how it needs to "flow" around the application - you need to work it out fairly well before you start coding or you will have massive changes to make later on!
Oh, and I'd totally agree with the Petzold recommendation - you seem to be trying to run before you can walk, and that ends up just confusing most people.
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks for your suggestions Griff.
Over the last few minutes I've been experimenting and managed to send variables between classes.
I'm now trying to readlines from a text file using StreamReader... but have not fully tried it yet.
I'm taking the challenge of converting a old Basic program written in 1984 to C#.
The program is a text adventure. It compiles an adventure script file and another program runs the compiled adventure file.
Brian
|
|
|
|
|
Hi Griff.
I have not had time to make your suggested changes yet.
I seem to have run into another problem as sr is not accepted in the code below.
I tried prog.sr but that does not work.
Brian
public static void Main(string[] args)
{
Program prog = new Program();
StreamReader sr = new StreamReader("demo.adv");
Console.WriteLine("Start of Program");
prog.y = 4;
prog.ReadHeader();
Console.WriteLine(prog.i);
prog.ReadVerbs();
prog.ReadNouns();
prog.ReadObjects();
prog.ReadStartRoom();
prog.ReadRooms();
prog.ReadMessages();
prog.ReadAutoActions();
prog.ReadActions();
sr.Close();
Console.Read();
}
public void ReadHeader()
{
Console.WriteLine("Read Header");
Text1 = sr.ReadLine(); // sr has a red line under (error)
Console.WriteLine(y);
i = 6;
}
|
|
|
|
|
Please put <pre> tags round your code so it is properly readable, as OriginalGriff suggested earlier. You can do it simply by selecting all the code text and using the code menu item at the top of the edit box.
|
|
|
|
|
Do you mean use <pre> so that they are displayed correctly when posting in Code Project?
eg
<PRE> public void static Main()
Brian
|
|
|
|
|
Yes, but if you use the code button, you can select the language so it highlights reserved words etc. So if I use <pre lang="c#"></pre> for some C# code it gets formatted as follows:
using System;
using System.IO;
using System.Text;
class Test
{
static void DoTest()
{
int result = 0;
Console.WriteLine("C# test result: {0}", result);
}
static void Main(string[] args)
{
for (int i = 0; i < args.Length; ++i)
{
Console.WriteLine("Arg {0}: {1}", i, args[i]);
}
try
{
DoTest();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
|
|
|
|
|
Hi Richard.
Do I use <pre lang C#> at the start of my program code
and use </pre> at the end of my code when posting my code?
Due to the changes in the time zone I'm off to bed now but will get your reply tomorrow thanks.
Brian
|
|
|
|
|
Yes, the tags are HTML tags and need to surround the text that is to be formatted. Please also ensure that the checkbox titled "Treat my content as plain text, not as HTML" below the edit box is unchecked, before posting.
|
|
|
|
|
sr is declared in Main: (and please, format your code blocks!)
public static void Main(string[] args)
{
Program prog = new Program();
StreamReader sr = new StreamReader("demo.adv"); So it is a local variable, which only exists inside the curly brackets in which it is declared: outside the Main method, it doesn't exist, and can't be accessed. And more importantly, when Main ends, it will be destroyed. What you need to do is pass it to the functions that need it:
public static void Main(string[] args)
{
Program prog = new Program();
StreamReader sr = new StreamReader("demo.adv");
Console.WriteLine("Start of Program");
prog.y = 4;
prog.ReadHeader(sr);
...
}
public void ReadHeader(StreamReader sr)
{
Console.WriteLine("Read Header");
Text1 = sr.ReadLine();
Console.WriteLine(y);
i = 6;
} The other solution is to move sr out of Main, and make it class level:
private StreamReader sr;
public static void Main(string[] args)
{
Program prog = new Program();
prog.sr = new StreamReader("demo.adv");
Console.WriteLine("Start of Program");
prog.y = 4;
prog.ReadHeader();
...
} And then all the instance methods in you class can access it.
In all seriousness, this is basic stuff, which will be explained - carefully - in the Petzold book, and you really do need to read it before embarking on this project - or you will make so many mistakes that when you look back at it in three months time you'll cringe and wish you hadn't shown 13,889,528 other people your code...
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks Griff.
I was hoping that by using the word public that I could pass it (sr) to function but this must only apply to variables.
I was thinking of reading the text file using the Main program rather than in classes like you suggested but I wanted to make the program easier to understand by breaking it into classes so that all the work is done in each of the classes. However I might still keep that option open.
Due to the difference in the time zone I'm about to head to bed now.
Thanks once again for all your help.
Brian
|
|
|
|
|
public and private are access modifiers - they contain if you are allowed to access something from outside a class, they don't control how you do it.
You are really going about this the wrong way: you're trying to change a monolithic program into a "C# program" but ignoring that "the c# way" is very different and much better once you get your head round it. What you will end up with is not a good C# program, and you won't learn much that is actually useful! And if you want to use C# for "real" projects then what you are doing here won't help because it's ignoring the whole point of languages like C# (and C++, and even the .NET version of VB!).
Sleep well, and when you wake up, start reading the Petzold book - I know it's more exciting to rush right in there and code, but you will learn in a structured manner and you'll soon understand why I'm saying "this is the wrong approach".
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi Griff.
I think your referring to the structure of a C# program. I made that mistake some years ago when I tried to convert a old program written in BASIC into Visual Basic just by changing some of the commands. Years ago programs were very messy with lots of 'GOTO' commands compared to the cleaner structure of programs these days. Now I study how a program works so I can write it more constructed and not copy the program exactly in how it is written.
For me I get a certain amount of enjoyment in writing some code in C# and seeing it work without errors. The adventure compiler I'm writing is not that important to me as it's just a test program to get some practice with; chances are I might rewrite the adventure compiler differently once I've learn more about C# such as the use of functions etc.
I have a more complex program I want to convert but it will wait until I have a better understanding of C#.
Brian
|
|
|
|
|
The problem is that that teaches you nothing good - it teaches you "bad habits" - because it worked, so why not do it again - instead of "good habits" which help you to make better programs later on.
And bad habits are very hard to break!
While you can make monolithic, goto strewn, pointer infused, impenetrable spaghetti code in C# (just as in any other language) that doesn't mean it's efficient. If the code you are "converting" uses arrays because they are there you don't learn about .NET's more modern Collections which do the hard work for you for example. Or Generics, or Linq, or ... the list goes on. While you don't "need" them, being able to sort, filter, transform, and process a whole collection in a single line of readable code saves you huge amounts of time and promotes reliable code as well (That's Linq for you!).
Unless you follow a course or book, you don't come into contact with them, so you don't even know they exist. So seriously: sit down with Petzold, start reading, and do the exercises! I know it's boring, and that leaping into code is way more fun - but it makes your life a whole load easier and more fun in the future...
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|