In the chapter "High-Quality Programming Code" will we learn in details when and how to use constants efficiently.
return dogCount;
}
But when we examine how static and non-static methods and fields can be accessed, not all combinations are allowed.
Accessing Non-Static Members from Non-Static Method
Non-static methods can access non-static fields and other non-static methods of the class. For example, in the
Dog
class we can declare methodPrintInfo()
, which displays information about our dog:Dog.cs public class Dog
{
// Static variable static int dogCount;
// Instance variables private string name;
private int age;
public Dog(string name, int age) {
this.name = name;
this.age = age;
dogCount += 1;
}
public void Bark() {
Console.Write("wow-wow");
}
// Non-static (instance) method public void PrintInfo()
{
// Accessing instance variables – name and age
Console.Write("Dog's name: " + this.name + "; age: "
+ this.age + "; often says: ");
// Calling instance method
this.Bark();
} }
Of course, if we create an object of the
Dog
class and call hisPrintInfo()
method:static void Main() {
Dog dog = new Dog("Doggy", 1);
dog.PrintInfo();
}
The result will be the following:
Dog's name: Doggy; age: 1; often says: wow-wow
Accessing Static Elements from Non-Static Method
We can access static fields and static methods of the class from non-static method. As we learned earlier, this is because static methods and variables are bound by class, rather than a specific method and the static elements can be accessed from any object of the class, even of external classes (as long as they are visible to them).
For example:
Circle.cs
public class Circle {
public static double PI = 3.141592653589793;
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public static double CalculateSurface(double radius) {
return (PI * radius * radius);
}
public void PrintSurface()
{
double surface = CalculateSurface(radius);
Console.WriteLine("Circle's surface is: " + surface);
} }
In the example, we provide access to the value of the static field
PI
of the non-static methodPrintSurface()
, by calling the static methodCalculateSurface()
. Let’s try to call this non-static method:static void Main() {
Circle circle = new Circle(3);
circle.PrintSurface();
}
After the compilation and the execution, the following result will be printed on the console:
Circle's surface is: 28.2743338823081
Accessing Static Elements of the Class from Static Method
We can call a static method or static field of the class from another static method without any problems.
For example, let’s consider our class for mathematical calculations. We have declared the constant
PI
, in it. We can declare a static method for finding the length of the circle (the formula for finding perimeter of a circle is πr, wherer
is the radius of the circle), that uses the constantPI
for calculating the perimeter of a circle. Then, to show that static method can call another static method, we can call the static method for finding the perimeter of a circle from the static methodMain()
:MyMathClass.cs public class MyMathClass
{
public const double PI = 3.141592653589793;
// The method applies the formula: P = 2 * PI * r static double CalculateCirclePerimeter(double r) {
// Accessing the static variable PI from static method return (2 * PI * r);
}
static void Main() {
double radius = 5;
// Accessing static method from other static method
double circlePerimeter = CalculateCirclePerimeter(radius);
Console.WriteLine("Circle with radius " + radius + " has perimeter: " + circlePerimeter);
} }
The code is compiled without errors and displays the following output:
Circle with radius 5.0 has perimeter: 31.4159265358979
Accessing Non-Static Elements from Static Method
Let’s look at the most interesting case of a combination of accessing non- static and static elements of the class – accessing non-static elements form a static method.
We should know that from static method we can neither access non-static fields, nor call non-static methods. This is because static methods are bound to the class and do not “know” any object of the class. Therefore, the keyword
this
cannot be used in static methods – it is bound to a specific instance of the class. When we try to access non-static elements of the class (fields or methods) from static method, we will always get a compilation error.Unauthorized Access to Non-Static Field – Example
If in our class
Dog
we try to declare a static methodPrintName()
, which returns as a result the value of the non-static fieldname
declared in the class:public static void PrintName() {
// Trying to access non-static variable from static method Console.WriteLine(name); // INVALID
}
Accordingly, the compiler will respond with an error message:
An object reference is required for the non-static field, method, or property 'Dog.name'
If we try to access the field in the method, via the keyword
this
:public void string PrintName() {
// Trying to access non-static variable from static method Console.WriteLine(this.name); // INVALID
}
The compiler will still not be satisfied and this time will fail to compile the class and will display the following message:
Keyword 'this' is not valid in a static property, static method, or static field initializer
Illegal Call of Non-Static Method from Static Method – Example Now we will try to call non-static method from static method. Let declare in our class
Dog
, the non-static methodPrintAge()
, which prints the value of the fieldage
:public void PrintAge() {
Console.WriteLine(this.age);
}
Accordingly, let’s try from the method
Main()
, which we declare in the classDog
, to call this method without creating an object of our class:static void Main() {
// Attempt to invoke non-static method from a static context PrintAge(); // INVALID
}
When we try to compile we will get the following error:
An object reference is required for the non-static field, method, or property 'Dog.PrintAge()'
The result is similar, if we try to cheat the compiler, trying to call the method via the keyword
this
:static void Main() {
// Attempt to invoke non-static method from a static context this.PrintAge(); // INVALID
}
Accordingly, as with the attempt to access the non-static field of a static method using the keyword
this
, the compiler displays the following error message and fails to compile our class:Keyword 'this' is not valid in a static property, static method, or static field initializer
From the examples, we can make the following conclusion:
Non-static elements of the class may NOT be used in a static context.
The problem with the access to non-static elements of the class of static method has a single solution – these non-static elements are accessed by reference to an object:
static void Main() {
Dog myDog = new Dog("Lassie", 2);
string myDogName = myDog.name;
Console.WriteLine("My dog \"" + myDogName +"\" has age of ");
myDog.PrintAge();
Console.WriteLine("years");
}
Accordingly, this code is compiled and the result is: