Sorry if this is a really stupid question, but I am messing around and fiddling with what I am learning from YouTube beginner tutorials and I'm kind of lost here. can anyone let me know why using the public access specifier before the fields break everything?
namespace ConsoleApp1
{
class Methods
{
static void Main(string[] args)
{
public int _first, _second, _third, _fourth, _fifth;
for (int i=1;i<=5;i++)
{
Console.WriteLine("Enter {0}st number:", i);
Console.ReadLine();
switch (i)
{
case 1:
_first = i;
break;
}
}
}
The problem is the scope.
The fields (inside functions or methods it's better use variable) in the scope of a function cannot be "public" or "protected" or... No, are private to the container scope, and, of course, doesn't need access word.
If you make a field outside the function you can make it public, private, internal... etc...
You cannot make fields out of object or structs.
namespace ConsoleApp1
{
public int _secondThing // baaaad
class Methods
{
public static int _thing; //good
int _thing; //good, it's private;
private int _thing; //good, it's the same
public int _firstThing; //good
static void Main(string[] args)
{
public int _first, _second, _third, _fourth, _fifth; //baaad
int _first, _second; //good
}
}
}
As DrkDeveloper mentioned it´s a question of the scope of your variables. Depending on where you define a variable it only exists within that specific scope and all of its child-scopes, but not in parent-scopes. So defining somethin at class-level makes it accessable in the entire class, this is in all of its members. Defining a variable within a member such as a method on the other hand makes that variable existing only in that specific scope - in that method. You can´t access it from anywhere outside its scope.
Your first code without the access-modifier works, because the variables are defined within that method - we call them local variables. The second code with the access-modifiers would turn those variables into members (fields in this case) of the class. So you´d define a member in a method that should have a class-scope. This of course does not work.
So you either leave your variables local, or make them public static within your class.
namespace ConsoleApp1
{
class Methods
{
public int _first, _second, _third, _fourth, _fifth;
static void Main(string[] args)
{
for (int i=1;i<=5;i++)
{
Console.WriteLine("Enter {0}st number:", i);
Console.ReadLine();
switch (i)
{
case 1:
_first = i;
break;
}
}
}
}
}
Related
I'm a total noob in c#, since today. I couldn't find a good tutorial or anything, that could solve this obviously dumb problem. Basically, I try to translate a program from Python to C#. Normally in Python I define constants in the constructor. Where the hell should I put them in c#? I tried to put them in the constructor then I put them in Main(), because there was this error. But the error persists.
static void Main(string[] args)
{
var _top = 0
...
}
public string[] topToken()
{
if (_top < _tokens.Count())
{ return _tokens[_top];}
_top is declared inside Main, so it's not going to have visibility inside the topToken method. It's a local variable, scoped only to Main.
To give your variables visibility for the entire class, you need to declare them outside of any method.
Ex:
public class SomeClass
{
public int someVariable; // all methods in SomeClass can see this
public void DoIt() {
// we can use someVariable here
}
}
Note, by makeing someVariable public, it also means other we can access it directly. For example:
SomeClass x = new SomeClass();
x.someVariable = 42;
If you want to prevent this and only allow the methods/properties/etc. of the class to be able to see the someVariable variable, you can declare it as private.
In cases where you need a public variable, it's usually best to declare it like this (this is an example of an auto-implemented property):
public class SomeClass
{
public int SomeVariable { get; set; }
public void DoIt() {
// we can use SomeVariable here
}
}
This uses
if you want _top to be available outside of the Main method, place it here:
int _top = 0; //here instead
static void Main(string[] args)
{
...
}
public string[] topToken()
{
if (_top < _tokens.Count())
{ return _tokens[_top];}
}
Change your code to this:
const int _top = 0;
static void Main(string[] args)
{
...
}
public string[] topToken()
{
if (_top < _tokens.Count())
{ return _tokens[_top];}
To make _top accessible throughout your class you have to declare it as a field or a constant. A field requires actual storage while a constant is simply replaced by the actual value by the compiler. As you described _top as a constant I decided to declare it as such.
If you need a field and not a constant you have to declare it static because it is accessed in a static method:
static int _top = 0;
Because there is no public or protected in the declaration of _top it is private to the class. If you prefer you can add private in front of the declaration but that will be the default if the visibility is missing.
I want to define a global structure in C# and use it in three separate subroutines. I have already created the structure but I don't know how to make it a global variable so I can use it in multiple sections of my code. Any help is appreciated.
public struct Simple
{
public int Position;
public bool Exists;
public double LastValue;
};
static void Main(string[] args)
{
Simple s;
s.Position = 1;
s.Exists = false;
s.LastValue = 5.5;
}
So I want to use a Simple structure in two other routines in my code and possible pass it to different form (multiple usage of one variable).
The closest thing to "global" in C# is "static". Simply define the class and all members as static and it'll be accessible from anywhere the containing namespace is referenced. EDIT as Servy correctly points out, the class itself does not have to be static; however doing so forces all members to be static at compile-time. Also, static members can have any visibility, so you can have a private static field used by a public static property or method, and you can have an internal static class that won't be visible outside its home assembly. Just being static doesn't automatically make it wide open.
However, a better pattern might be the Singleton; you define a class that has one static instance of itself, that can then be passed around. The benefit is that you can still deal with the object as an instance class if you want to, but the same instance is available everywhere using a static getter. Here's some reading material: http://csharpindepth.com/Articles/General/Singleton.aspx
In your case it appears that you have a object as a local variable in your main method that you need to use in another method. The appropriate solution in this context is to add a parameter to that other method. Take a look at this example:
public class MyObject
{
public int Value;
}
public static void Main(string[] args)
{
MyObject obj = new MyObject();
obj.Value = 42;
PrintObject(obj);
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}
public static void PrintObject(MyObject obj)
{
Console.WriteLine(obj.Value);
}
am learning C# and have written a simple bit of code, but i don't understand why i have to declare the variables userChoice and numberR within the scope of the Main method and not within the scope of the class. If i declare it within the class like this, i get build errors
using System;
namespace FirstProgram
{
class Program
{
string userChoice;
int numbeR;
static void Main()
{
Console.WriteLine("Write a number...");
userChoice = Console.ReadLine();
numbeR = Convert.ToInt32(userChoice);
Console.WriteLine("You wrote {0}", numbeR);
Console.ReadLine();
}
}
}
But only this will give me no errors:
using System;
namespace FirstProgram
{
class Program
{
static void Main()
{
string userChoice;
int numbeR;
Console.WriteLine("Write a number...");
userChoice = Console.ReadLine();
numbeR = Convert.ToInt32(userChoice);
Console.WriteLine("You wrote {0}", numbeR);
Console.ReadLine();
}
}
}
Shouldn't i be able to use those two variables within Main just by declaring them in the Class like above? I am confused... thanks for any advice.
You can't do it because Main() is a static function. Your variables are declared as instance variables and can only be accessed on an instance of the Program class. If you declare userChoice and numbeR as static variables, it will compile.
static string userChoice;
static int numbeR;
static void Main()
{
//your code
}
Static members mean you can use the member without instantiating the class. Imagine:
public class MyClass
{
public static int StaticInt;
public int NonStaticInt;
}
means you could do:
MyClass.StaticInt = 12; // legal
MyClass.NonStaticInt = 12; // error, can't staticly access instance member
and all classes would have access to that change, since there is only one MyClass.StaticInt in your program. To change NonStaticInt, you would have to create an instance of that class, like so:
MyClass mine = new MyClass();
mine.NonStaticInt = 12; // legal
mine.StaticInt = 12; // Error, cannot access static member on instance class.
You have to make your variables static since your Main method is static.
Since Main is static, your variables would also need to be static in order to be used like this. If you declare them as:
static string userChoice;
static int numbeR;
Then it will work.
You currently have them declared inside an instance of a Program object. However, static methods (such as Main) are part of the type, not a specific instance.
because Main is static
if you declare the variables (a.k.a. fields) as static too you can declare them in the class
static string userChoice;
static int numbeR;
Non static methods and variables are called instance methods and variables. Instance variables relates to a specific object while static variables are shared among all created objects within the class.
The rules are that static methods can only call static methods and access static variables, but instance methods can call both static and non static variables and methods.
The reason is because Main() is a static method and the two class fields (userChoice and numbeR) are instance fields.
Main() can be called statically, but the two class fields won't be defined until an instance of the Program class is created.
The Main() method is declared as static. However, in your first code sample you declare two variables (userChoice & number) as instance variables. The static Main() method does not belong to a specific object, but to a certain type. Your variables however do belong to a specific instance of the Program type. You cannot use instance variables in a static method.
The problem is that Main is static. You will have to declare the variables userChoice and numbeR as static. Then it will compile. Here is the corrected example:
using System;
namespace FirstProgram
{
class Program
{
static string userChoice;
static int numbeR;
static void Main()
{
Console.WriteLine("Write a number...");
userChoice = Console.ReadLine();
numbeR = Convert.ToInt32(userChoice);
Console.WriteLine("You wrote {0}", numbeR);
Console.ReadLine();
}
}
}
I am porting some code from C# to C++. I am not sure how do I create a class like the static class in C#.
// in C#
public static temperatureClass{
private static int offset = 50;
private static Context context;
public static calculateTemperature(){
//use a;
//use context;
}
public static Context con{
set{
context = value;
}
}
}
int main() {
Context con1;
temperatureClass.con = con1; //con1 is a
temperatureClass.calculateTemperature();
}
Basically the temperatureClass is a utility class to perform calculation that no instances would be created.
I have a few questions:
Should the C++ version of calculateTemperature remain as static?
How could I initialize the int offset in C++ if I keep it as static because it is used by static calculateTempearture function?
Should I keep the con accessor as static in C++ as I need to set the context?
or more generally, what is the way of implementing an utility class like that in C++?
The C++ version could very well be a class containing only static members
The offset variable being of integral type, it can be initialized the same way as in C# if declared static (but you might want to add a const)
If context is static, the accessor must also be static as static member functions cannot access non-static member variables
Note that I don't think that this is good design. From my point of view, there isn't much sense in "whole static classes" in C++, and I'd rather use a set a free functions in a isolated namespace. If you choose the "static class" approach anyway, I'd recommend declaring the default constructor private to make it clear that the class has not point in being instantiated.
In C++, you don't need static classes, because you can have functions at namespace scope. In C#, static classes are needed because all functions have to be at class scope.
I'd do something like this:
// temp.h
namespace temperature {
void calculateTemperature(const Context& context);
}
// temp.cpp
namespace { // private stuff
int offset = 50;
}
namespace temperature {
void calculateTemperature(Context context){
//use a;
//use context;
}
}
// programm.cpp
#include "temp.h"
int main() {
Context con1;
temperature.calculateTemperature(con1);
}
Static classes in C# are simply classes that can not be instantiated, and contains only static method.
There's no explicit static class in C++, but you can simply achieve the same in C++ by hiding the constructors as private, and providing the public static methods.
By static initialization:
class temperatureClass {
private:
static int offset;
};
int temperatureClass::offset = 50;
You can leave it static, so you will follow the original as much it's possible.
Some air code, without letting it go through the compiler (so if there's an error, please tell me, I will fix it, but I think most of the stuff should have been translated correctly straightforward from C# to C++).
class temperatureClass
{
private:
static int offset = 50;
static Context context;
temperatureClass(){}; // avoid instantiation
public:
static void calculateTemperature()
{
//use a;
//use context;
}
static void SetCon(Context c)
{
context = c;
}
}; // dont forget semicolon in C++ :-)
int main()
{
Context con1;
temperatureClass::SetCon(con1);
temperatureClass::calculateTemperature();
}
(if this is a good design or not is another question, but that's independent of C# or C++)
What is the usage of global:: keyword in C#? When must we use this keyword?
Technically, global is not a keyword: it's a so-called "contextual keyword". These have special meaning only in a limited program context and can be used as identifiers outside that context.
global can and should be used whenever there's ambiguity or whenever a member is hidden. From here:
class TestApp
{
// Define a new class called 'System' to cause problems.
public class System { }
// Define a constant called 'Console' to cause more problems.
const int Console = 7;
const int number = 66;
static void Main()
{
// Error Accesses TestApp.Console
Console.WriteLine(number);
// Error either
System.Console.WriteLine(number);
// This, however, is fine
global::System.Console.WriteLine(number);
}
}
Note, however, that global doesn't work when no namespace is specified for the type:
// See: no namespace here
public static class System
{
public static void Main()
{
// "System" doesn't have a namespace, so this
// will refer to this class!
global::System.Console.WriteLine("Hello, world!");
}
}