What Does 'Static' Mean in C#

What does `static` mean in c#?

In short, static effectively means "associated with a type instead of any one instance of the type". So there's one set of static variables for a type (within an AppDomain) whether you have 0 instances or a million; you don't need an instance to access a static member, etc.

The exact point of initialization of static variables depends on whether there's also a static constructor or not, but very broadly speaking it's "once, usually before anything significant happens in the class". (See this blog post for a more detailed description.)

While readonly fields can be either static or instance (i.e. related to the type or related to an instance of the type), const values are always implicitly static (they're compile-time constants, so it wouldn't make sense to have one copy per instance).

You may sometimes see static being described as "shared between all instances of a type" - I personally dislike that description, as it suggests that there has to be at least one instance... whereas actually, you don't need any instances in order to use a static member. I prefer to think of them as entirely separate, rather than being "shared" between instances.

What is the meaning of static in differents parts of the code?

class modifier

When static is applied to a class it indicates four attributes.

  • Contains only static members.
  • Cannot be instantiated.
  • Is sealed.
  • Cannot contain Instance Constructors.

property or function modifier (and events and methods)

When applied to properties and functions, e.g.

public Thing
{
static int SharedCount { get; set; }

static string GenerateName()
{
// ...
}
}

it means that the properties and functions will be accessible via the type name, without instantiating the class. This properties and functions will not be accessible via an instance of the class. So, both

var i = Thing.SharedCount;
var s = Thing.GenerateName();

Are valid and correct statements, Where as

var i = new Thing().SharedCount;
var s = this.GenerateName();

are both incorrect.

Code in functions and properties declared with the static modifier cannot access non-static members of the class.


member variables

Member variables declared with a static modifier, e.g.

class Thing
{
private static int sharedCount = 0;
private static readonly IDictionary<string, int> ThingLookup =
new Dictionary<string, int>
{
{ "a", 1 },
{ "b", 2 }
};
}

are shared by all static functions and properties and by all instances of the class.


static constructors

When applied to constructors, e.g.

class Thing
{
static Thing()
{
\\ Do this once and first.
}
}

static means the constructor will run once per AppDomain, when the type is first accessed. There are special edge cases around this.


operators

When an operator is overloaded for a type, this is always declared as static, e.g.

public static Thing operator +(Thing left, Thing right)
{
// Something special to do with things.
}

It is not logical for this to be declared at an instance level since operators must apply to types.

These distinctions are explained here, here, here and here.

What's a static method in C#?

A static function, unlike a regular (instance) function, is not associated with an instance of the class.

A static class is a class which can only contain static members, and therefore cannot be instantiated.

For example:

class SomeClass {
public int InstanceMethod() { return 1; }
public static int StaticMethod() { return 42; }
}

In order to call InstanceMethod, you need an instance of the class:

SomeClass instance = new SomeClass();
instance.InstanceMethod(); //Fine
instance.StaticMethod(); //Won't compile

SomeClass.InstanceMethod(); //Won't compile
SomeClass.StaticMethod(); //Fine

What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method?

A static variable shares the value of it among all instances of the class.

Example without declaring it static:

public class Variable
{
public int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}

public class Exercise
{
static void Main()
{
Variable var = new Variable();
var.test();
Variable var1 = new Variable();
var1.test();
Console.ReadKey();
}
}

Explanation: If you look at the above example, I just declare the int variable. When I run this code the output will be 10 and 10. Its simple.

Now let's look at the static variable here; I am declaring the variable as a static.

Example with static variable:

public class Variable
{
public static int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}

public class Exercise
{
static void Main()
{
Variable var = new Variable();
var.test();
Variable var1 = new Variable();
var1.test();
Console.ReadKey();
}
}

Now when I run above code, the output will be 10 and 15. So the static variable value is shared among all instances of that class.

What does static mean in C?

  1. A static variable inside a function keeps its value between invocations.
  2. A static global variable or a function is "seen" only in the file it's declared in

(1) is the more foreign topic if you're a newbie, so here's an example:

#include <stdio.h>

void foo()
{
int a = 10;
static int sa = 10;

a += 5;
sa += 5;

printf("a = %d, sa = %d\n", a, sa);
}

int main()
{
int i;

for (i = 0; i < 10; ++i)
foo();
}

This prints:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.

(2) Is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.

Quoting Wikipedia:

In the C programming language, static
is used with global variables and
functions to set their scope to the
containing file. In local variables,
static is used to store the variable
in the statically allocated memory
instead of the automatically allocated
memory. While the language does not
dictate the implementation of either
type of memory, statically allocated
memory is typically reserved in data
segment of the program at compile
time, while the automatically
allocated memory is normally
implemented as a transient call stack.

And to answer your second question, it's not like in C#.

In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.

What is the difference between public static, public and static method?

public by itself means this is an instance-based member that is accessible to external callers (those with access to the type itself).

static by itself means the member is not instance-based: you can call it without needing any particular instance (or even any instance at all); without an accessibility qualifier, non-public is assumed - so the member will not be accessible to external callers.

public static is a static method that is accessible to external callers.

Memory usage is identical in both cases: any variables declared in the method are scoped to the method-call itself (as an implementation detail: via the stack; also: I'm assuming no "captured variables", and no async or yield usage),

Nothing in this is specific to ASP.NET / MVC. However, "action" methods on controllers are, IIRC, expected to be public / instance, so with the public modifier, and without the static modifier.

Basically:

Accessibility:

  • none specified: defaults to "private" (or "internal" for outer-classes)
  • "private": only available to code inside that type
  • "protected": available to code inside that type or sub-types
  • "internal": available to code in the same assembly
  • "protected internal": either "protected" or (union) "internal"
  • "public": available to all callers with access to the type

Static / etc:

  • none specified: instance-based; an instance is required, and code has automatic access to instance-members (via this.) and static members
  • "static": no instance is required; code has automatic access to static members only

What does the static keyword mean?

The difference between #1 and #2 is that in #1, isMin is an instance member function of the class Program, therefore you have to create an instance of the Program class

 Program min = new Program()

and only then call the instance member function isMin:

 min.isMin(..)



In #2, isMin is a static member function of the Program class, and since Main is also a static member function of the same class, you can make a direct call to isMin from the Main function.

Both are valid. The static function Main is the "entry point" into the program which means it gets executed first. The rest is just Object-Oriented semantics.

EDIT

It seems that in order to better illustrate the point an example would be in order.

The two programs below are pretty useless outside of their intended purpose of showing the differences between encapsulating your program logic into objects, and the alternative -using static functions.

The program defines two operation and will work on two numbers (10 and 25 in the example). As the program runs, it will trace its' operations to a log file (one for each number). It is useful to imagine that the two operations could be replaced by more serious algorithms and that the two numbers could be replaced by a series of more useful input data.

//The instance-based version:
class Program
{
private System.IO.StreamWriter _logStream;
private int _originalNumber;
private int _currentNumber;

public Program(int number, string logFilePath)
{
_originalNumber = number;
_currentNumber = number;
try
{
_logStream = new System.IO.StreamWriter(logFilePath, true);
_logStream.WriteLine("Starting Program for {0}", _originalNumber);
}
catch
{
_logStream = null;
}
}
public void Add(int operand)
{
if (_logStream != null)
_logStream.WriteLine("For {0}: Adding {1} to {2}", _originalNumber, operand, _currentNumber);
_currentNumber += operand;
}
public void Subtract(int operand)
{
if (_logStream != null)
_logStream.WriteLine("For {0}: Subtracting {1} from {2}", _originalNumber, operand, _currentNumber);
_currentNumber -= operand;
}
public void Finish()
{
Console.WriteLine("Program finished. {0} --> {1}", _originalNumber, _currentNumber);
if (_logStream != null)
{
_logStream.WriteLine("Program finished. {0} --> {1}", _originalNumber, _currentNumber);
_logStream.Close();
_logStream = null;
}
}

static void Main(string[] args)
{
Program p = new Program(10, "log-for-10.txt");
Program q = new Program(25, "log-for-25.txt");

p.Add(3); // p._currentNumber = p._currentNumber + 3;
p.Subtract(7); // p._currentNumber = p._currentNumber - 7;
q.Add(15); // q._currentNumber = q._currentNumber + 15;
q.Subtract(20); // q._currentNumber = q._currentNumber - 20;
q.Subtract(3); // q._currentNumber = q._currentNumber - 3;

p.Finish(); // display original number and final result for p
q.Finish(); // display original number and final result for q
}
}

Following is the static functions based implementation of the same program. Notice how we have to "carry our state" into and out of each operation, and how the Main function needs to "remember" which data goes with which function call.

class Program
{
private static int Add(int number, int operand, int originalNumber, System.IO.StreamWriter logFile)
{
if (logFile != null)
logFile.WriteLine("For {0}: Adding {1} to {2}", originalNumber, operand, number);
return (number + operand);
}
private static int Subtract(int number, int operand, int originalNumber, System.IO.StreamWriter logFile)
{
if (logFile != null)
logFile.WriteLine("For {0}: Subtracting {1} from {2}", originalNumber, operand, number);
return (number - operand);
}
private static void Finish(int number, int originalNumber, System.IO.StreamWriter logFile)
{
Console.WriteLine("Program finished. {0} --> {1}", originalNumber, number);
if (logFile != null)
{
logFile.WriteLine("Program finished. {0} --> {1}", originalNumber, number);
logFile.Close();
logFile = null;
}
}

static void Main(string[] args)
{
int pNumber = 10;
int pCurrentNumber = 10;
System.IO.StreamWriter pLogFile;
int qNumber = 25;
int qCurrentNumber = 25;
System.IO.StreamWriter qLogFile;

pLogFile = new System.IO.StreamWriter("log-for-10.txt", true);
pLogFile.WriteLine("Starting Program for {0}", pNumber);
qLogFile = new System.IO.StreamWriter("log-for-25.txt", true);
qLogFile.WriteLine("Starting Program for {0}", qNumber);

pCurrentNumber = Program.Add(pCurrentNumber, 3, pNumber, pLogFile);
pCurrentNumber = Program.Subtract(pCurrentNumber, 7, pNumber, pLogFile);
qCurrentNumber = Program.Add(qCurrentNumber, 15, qNumber, qLogFile);
qCurrentNumber = Program.Subtract(qCurrentNumber, 20, qNumber, qLogFile);
qCurrentNumber = Program.Subtract(qCurrentNumber, 3, qNumber, qLogFile);

Program.Finish(pCurrentNumber, pNumber, pLogFile);
Program.Finish(qCurrentNumber, qNumber, qLogFile);
}
}

Another point to note is that although the first instance-based example works, it is more common in practice to encapsulate your logic in a different class which can be used in the Main entry point of your program. This approach is more flexible because it makes it very easy to take your program logic and move it to a different file, or even to a different assembly that could even be used by multiple applications. This is one way to do that.

// Another instance-based approach
class ProgramLogic
{
private System.IO.StreamWriter _logStream;
private int _originalNumber;
private int _currentNumber;

public ProgramLogic(int number, string logFilePath)
{
_originalNumber = number;
_currentNumber = number;
try
{
_logStream = new System.IO.StreamWriter(logFilePath, true);
_logStream.WriteLine("Starting Program for {0}", _originalNumber);
}
catch
{
_logStream = null;
}
}
public void Add(int operand)
{
if (_logStream != null)
_logStream.WriteLine("For {0}: Adding {1} to {2}", _originalNumber, operand, _currentNumber);
_currentNumber += operand;
}
public void Subtract(int operand)
{
if (_logStream != null)
_logStream.WriteLine("For {0}: Subtracting {1} from {2}", _originalNumber, operand, _currentNumber);
_currentNumber -= operand;
}
public void Finish()
{
Console.WriteLine("Program finished. {0} --> {1}", _originalNumber, _currentNumber);
if (_logStream != null)
{
_logStream.WriteLine("Program finished. {0} --> {1}", _originalNumber, _currentNumber);
_logStream.Close();
_logStream = null;
}
}
}

class Program
{
static void Main(string[] args)
{
ProgramLogic p = new ProgramLogic(10, "log-for-10.txt");
ProgramLogic q = new ProgramLogic(25, "log-for-25.txt");

p.Add(3); // p._number = p._number + 3;
p.Subtract(7); // p._number = p._number - 7;
q.Add(15); // q._number = q._number + 15;
q.Subtract(20); // q._number = q._number - 20;
q.Subtract(3); // q._number = q._number - 3;

p.Finish();
q.Finish();
}
}

What is a static class?

A static class cannot be instantiated, and can contain only static members. Hence, the calls for a static class are as: MyStaticClass.MyMethod(...) or MyStaticClass.MyConstant.

A non static class can be instantiated and may contain non-static members (instance constructors, destructor, indexers). A non-static member of a non-static class is callable only through an object:

MyNonStaticClass x = new MyNonStaticClass(...);
x.MyNonStaticMethod(...);

What is the meaning of static in differents parts of the code?

class modifier

When static is applied to a class it indicates four attributes.

  • Contains only static members.
  • Cannot be instantiated.
  • Is sealed.
  • Cannot contain Instance Constructors.

property or function modifier (and events and methods)

When applied to properties and functions, e.g.

public Thing
{
static int SharedCount { get; set; }

static string GenerateName()
{
// ...
}
}

it means that the properties and functions will be accessible via the type name, without instantiating the class. This properties and functions will not be accessible via an instance of the class. So, both

var i = Thing.SharedCount;
var s = Thing.GenerateName();

Are valid and correct statements, Where as

var i = new Thing().SharedCount;
var s = this.GenerateName();

are both incorrect.

Code in functions and properties declared with the static modifier cannot access non-static members of the class.


member variables

Member variables declared with a static modifier, e.g.

class Thing
{
private static int sharedCount = 0;
private static readonly IDictionary<string, int> ThingLookup =
new Dictionary<string, int>
{
{ "a", 1 },
{ "b", 2 }
};
}

are shared by all static functions and properties and by all instances of the class.


static constructors

When applied to constructors, e.g.

class Thing
{
static Thing()
{
\\ Do this once and first.
}
}

static means the constructor will run once per AppDomain, when the type is first accessed. There are special edge cases around this.


operators

When an operator is overloaded for a type, this is always declared as static, e.g.

public static Thing operator +(Thing left, Thing right)
{
// Something special to do with things.
}

It is not logical for this to be declared at an instance level since operators must apply to types.

These distinctions are explained here, here, here and here.



Related Topics



Leave a reply



Submit