I've recently picked up C# as another language to further my knowledge into other languages, but as experimenting to get used to the syntax of the language, I encountered this problem when using the public static void Main(); and calling methods inside the same class. My code was as follows:
namespace TestingProject
{
class Class1
{
public static void Main()
{
System.Console.WriteLine("This is nothing but a test \n Input 'test'");
var UserInput = System.Console.ReadLine();
string Input = this.ValidateInput(UserInput);
System.Console.WriteLine(Input);
System.Console.WriteLine();
}
protected string ValidateInput(string Variable)
{
var VarReturn = (string)null;
if (string.Equals(Variable, "test"))
{
VarReturn = "Correct \n";
}
else
{
VarReturn = "Incorrect \n";
}
return VarReturn;
}
}
}
So, from what i've researched it turns out that you cannot use the this syntax to call internal private methods from a static function.
So I tried self but this returned no avail (assuming since languages such as python, PHP allow self), so tried the following:
string Input = TestingProject.Class1.ValidateInput(UserInput);
To be presented with the following message:
Error 1 An object reference is required for the non-static field,
method, or property
'TestingProject.Class1.ValidateInput(string)' C:\Users\xxx\AppData\Local\Temporary
Projects\ClassProject\Class1.cs 14 28 ClassProject
So then, I found this little gem which did solve the problem :
var CurrClass = new Class1();
and called the protected method as so:
var CurrClass = new Class1();
string Input = CurrClass.ValidateInput(UserInput);
Which did surprise me that this was the only available way to call internal non-staic private methods, so my overall question is:
Is there a way to call non-static methods which are protected/private without initializing a new variable to contain the current object?
The problem is that your Main method is static. A static method can not access non-static methods, even within the same class, without having an instance of the object. That is the entire point of having a static method: you don't have a concrete object to work with. It's outside of the scope of the other instance methods.
Related
I see code written like this:
static void Main(string[] args)
{
var name = GetInfo(); //this variable contains the method below
Console.Writeline(name)
}
static string GetInfo()
{
string name = "MyName";
return (name);
}
Let's use the typical box example. What's a good example for method inside it?
In other words, what does it mean 'a value' = 'a method that does something'
Its not assigning a method, it is just getting the result of that executed method. In this way you can reuse GetInfo(); in other places where ever you need this name.
I am having trouble with this piece of code and I can't figure out how to get it to work. I can't figure out what the problem is as to me it looks like it should work. The string array called m_nameList on both places are marked as 'An object reference required for the non static feild, method, or property 'Solutionname.classname.m_nameList'
the code:
public static bool CheckVacantSeats(int seatNumber)
{
if (m_nameList[seatNumber] == null)
{
return true;
}
return false;
}
m_nameList is an array that is declared in an constructor before this static bool:
public SeatManager(int maxNumberOfSeats)
{
m_totNumOfSeats = maxNumberOfSeats;
m_nameList = new string[m_totNumOfSeats];
m_priceList = new double[m_totNumOfSeats];
}
I am calling the CheckVacantSeat from another class with this:
bool validSeats = SeatManager.CheckVacantSeats(seatNumber, m_nameList);
I can't figure out what is wrong with it. So i need some help figuring out why m_nameList does not work for me?
Thanks in advance!!
//Regards
The problem is that you have marked your method as static. Since it is static, it has "no" state, and cannot access class members which are not marked as static.
You can mark m_nameList as static, but that means that it's value is shared across all reads and writes. m_nameList looks like a simple lookup table so maybe this is what you want?
Recommended reading is static and Static Classes and Static Members.
Your function is static, but your variables are not static.
Well your call is wrong for a start, your method CheckVacantSeats only accepts one parameter so you can't call it with two??!
CheckVacantSeats(int seatNumber)
SeatManager.CheckVacantSeats(seatNumber, m_nameList);
your method is also static so there's no point having a constructor.
I think what your after is:
SeatManager seatManager = new SeatManager(maxNumberOfSeats);
seatManager.CheckVacantSeats(seatNumber);
Also
public bool CheckVacantSeats(int seatNumber)
{
if (m_nameList[seatNumber] == null)
{
return true;
}
return false;
}
You are mixing two concepts: an instance initialized with a constructor, and a static class with static members. You cannot expect a static member method to access a non-static field. I guess your m_nameList field is static as well, otherwise your code wouldn't even compile. You should choose either way:
make all SeatManager's members non-static;
turn the SeatManager class into a static class having all members static.
Since you need to initialize the SeatManager with the total number of seats, the better way seems to be No. (1). Then instead of SeatManager.CheckVacantSeats() you would call an instance like mySeatManager.CheckVacantSeats(). Even in case there will always be just one instance of SeatManager — a singleton — this approach is better. With a singleton, you could end up with a public static SeatManager Instance { get; set; } property in SeatManager and work with it like this: SeatManager.Instace.CheckVacantSeats(). This is usually called a singleton pattern.
Can I locally reference a class in C#, instead of an instance of a class? The following code won't compile but, as an example, something like:
void someFunc()
{
var a = System.Math;
var b = a.Abs(4);
}
edit: In the real program it's not the System.Math class and I'm wanting to construct the class and return the constructed value. I didn't think originally that the context in which I wanted to use the class would be relevent, and probably it shouldn't be.
Anastasiosyal has an interesting idea with using a local Delegate to do it.
You can reference a class:
Type math = typeof(System.Math);
But you cannot call static methods on it using regular dot syntax:
// Wont compile:
math.Abs(5);
If you just want to shorten (and IMHO obfuscate) your code, you can reference classes with aliases via a using directive:
// Untested, but should work
namespace MyUnreadableCode {
using m = System.Math;
class Foo {
public static Int32 Absolut(Int32 a) {
return m.Abs(a);
}
}
}
You cannot assign a variable a value of a static class. The question is why would you want to do this, there are probably other ways that you could tackle your problem
e.g. you could use delegates to assign the operation you want to perform:
Func<int,int> operation = Math.Abs;
// then you could use it like so:
int processedValue = operation(-1);
In c# they're called Types. And you can assign them like:
Type a = typeof(SomeClass);
However, you would have to instantiate it to use it. What I believe you want is a static import like in java, but unfortunately, they do not exist in c#.
Short answer: Not like what you have above.
In C# 6.0 they introduced a static import feature, which can solve the problem.
using static System.Math;
class MyProgram
{
static void Main(string[] args)
{
var b = Abs(4); // No need to specify the name of Math class
}
}
As I understand you need to refer to the class with short name? try this (on top of the file, inside using statements section):
using m = System.Math;
later in your code:
m.Abs(...)
Makes sense?
No. It's not possible to treat a Type as a value where instance methods bind to static methods on the original type. In order to do this you would need to construct a new type which forwards it's method calls to the original type.
class MyMath {
public int Abs(int i) {
return Math.Abs(i);
}
}
var x = new MyMath();
How do I explicitly refer to the parameter as opposed to the member variable?
static recursive{
public static List<string> output = new List<string>();
public static void Recursive(List<string> output){
...
}
}
An unqualified reference will always refer to the parameter because it is at a more local scope.
If you want to refer to the member variable, you need to qualify it with the name of the class (or this, for non-static member variables).
output = foo; // refers to the parameter
recursive.output = foo; // refers to a static member variable
this.output = foo; // refers to a non-static member variable
But you should probably change the name anyway. It makes your code much easier to read.
And you shouldn't have public static variables at all. All of the .NET coding style guidelines strongly recommend properties instead of exposing public fields. And since those are always camel-cased, this problem solves itself.
public static void Recursive(List<string> output){
...
}
The code in the block that refers to output will always be local & not the member variable.
If you wish to refer to member variable, you could use recursive.output.
When you are inside the Recursive static method output will point to the argument of the method. If you want to point to the static field use the name of the static class as prefix: recursive.output
Give your member variable another name.
The convention is to use Camelcasing on public static members.
public static List<string> Output = new List<string>();
public static void Recursive( List<string> output )
{
Output = output;
}
You can explicitly reference recursive.output to indicate the static member, but it would be cleaner to rename either the parameter or the member.
I know of no way to explicitly refer to a parameter. The way this is usually handled is to give member variables a special prefix such as _ or m_ so that parameters will never have exactly the same name. The other way is to refer to member variables using this.var.
public class MyClass {
public int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(number); // prints value of "number" parameter
}
}
EDIT::
For static fields is required name of class instead of "this":
public class MyClass {
public static int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(MyClass.number); // prints value of "number" parameter
}
}
I have got these two classes interacting and I am trying to call four different classes from class one for use in class two.
The methods are public and they do return values but for some reason there is not a connection being made.
The error I get when I try is: "An object reference is required for the nonstatic field, method, or property 'GradeBook.[method I want called]'"
I have everything initialized. I don't want to create the methods as static. I read over the specifics of my assignment again and I'm not even supposed to but I can't seem to get this to work anyway I word it.
myGradeBook.[method]
GraceBook.[method]
It all seems to create errors.
The current errors:
The best overloaded method match or 'System.Console.WriteLine(string, object)' has some invalid arguments.
Arugment '2': cannot convert from 'method group' to 'object'
I'm not even sur what those mean....
EDIT:
I just fixed that problem thanks to the Step Into feature of Visual Studio.
I don't know why it took me so long to use it.
You're trying to call an instance method on the class. To call an instance method on a class you must create an instance on which to call the method. If you want to call the method on non-instances add the static keyword. For example
class Example {
public static string NonInstanceMethod() {
return "static";
}
public string InstanceMethod() {
return "non-static";
}
}
static void SomeMethod() {
Console.WriteLine(Example.NonInstanceMethod());
Console.WriteLine(Example.InstanceMethod()); // Does not compile
Example v1 = new Example();
Console.WriteLine(v1.InstanceMethod());
}
It sounds like you're not instantiating your class. That's the primary reason I get the "an object reference is required" error.
MyClass myClass = new MyClass();
once you've added that line you can then call your method
myClass.myMethod();
Also, are all of your classes in the same namespace? When I was first learning c# this was a common tripping point for me.
You have to create a variable of the type of the class, and set it equal to a new instance of the object first.
GradeBook myGradeBook = new GradeBook();
Then call the method on the obect you just created.
myGradeBook.[method you want called]
For example 1 and 2 you need to create static methods:
public static string InstanceMethod() {return "Hello World";}
Then for example 3 you need an instance of your object to invoke the method:
object o = new object();
string s = o.InstanceMethod();