.NET Glossary#
Terminology, Lingo, and Clarification for .NET.
Var
Type / Implicitly Typed Local Variables#
Simple Definition:
- Sets the variable type to whatever is first assigned.
Simple Why:
var x = new MyLongClassName<int>()
reads better thanMyLongClassName<int> x = new MyLongClassName<int>();
.- Helps decouple design and write code faster at expense of some legibility if not careful.
- Read more here.
How
Input:
var x = 1; // These lines are the same
int x = 1; // These lines are the same
var x; // Error: Need to assign type
var x = 1;
x = "hi"; // Error: "hi" not an int
Value Type#
Simple Definition:
- A Value Type is a value that directly holds itself in the variable's memory address.
- In Microsoft's implementation, most built-in types are primitive.
- NOTE: Certain uses of value types are treated as references OR converted via "Boxing".
- They are usually stored on the stack, but this is an implementation detail.
Simple Why:
How
Reference Type#
Simple Definition:
- A Reference Type is a value that is accessed by a different memory address.
- In Microsoft's implementation, strings and most objects are references.
- NOTE: Certain uses of value types are treated as references OR converted via "Boxing".
- They are usually stored on the heap, but this is an implementation detail.
Simple Why:
- Allows for fancy garbage collection and other cool stuff.
- Our stack won't blow up trying to load a massive string / object. It is only 1MB/4MB
How
Objects (like this examples Student
class) are references:
Student ed = new Student();
ed.studentName = "Ed";
Console.WriteLine(ed.studentName); // Ed
ChangeReferenceType(ed);
Console.WriteLine(ed.studentName); // Not Ed
static void ChangeReferenceType(Student student)
{
student.studentName = "Not Ed";
}
class Student
{
public string studentName;
}
Notice how trying to change just the string doesn't change the object!
Student ed = new Student();
ed.studentName = "Ed";
Console.WriteLine(ed.studentName); // Ed
ChangeStringReference(ed.studentName);
Console.WriteLine(ed.studentName); // Ed (!)
ChangeClassReference(ed);
Console.WriteLine(ed.studentName); // Not Ed
static void ChangeStringReference(string studentName)
{
studentName = "Not Ed";
}
static void ChangeClassReference(Student student)
{
student.studentName = "Not Ed";
}
class Student
{
public string studentName;
}
So what's going on here?
C# Passes-By-Value (in this case, the memory address). Take a look on why object properties vs strings act different:
Here's a simplified version of our reference being Passed-By-Value:
string s = "hi!";
Console.WriteLine(s); // s = "hi!"
ChangeValue(s);
Console.WriteLine(s); // s = "hi!" ...wait, what?
static void ChangeValue(string s)
{
s = "bye!";
Console.WriteLine(s); // s = "bye!"
}
If Absolutely Necessary, we can resolve this by using ref
which Passes-By-Reference.
string s = "hi!";
Console.WriteLine(s); // s = "hi!"
ChangeValue(ref s);
Console.WriteLine(s); // s = "bye!"
static void ChangeValue(ref string s)
{
s = "bye!";
Console.WriteLine(s); // s = "bye!"
}
Or we can defer to using a mutable object, like StringBuilder:
using System.Text;
StringBuilder s = new StringBuilder("hi!");
Console.WriteLine(s); // s = "hi!"
ChangeValue(s);
Console.WriteLine(s); // s = "bye!"
static void ChangeValue(StringBuilder s)
{
s.Clear();
s.Append("bye!");
Console.WriteLine(s); // s = "bye!"
}
Apologies if I didn't do well explaining this, its fairly nuanced!
Boxing / Unboxing#
Simple Definition:
- Conversion of a value type to a reference type.
- This is usually not desired because it eats extra CPU cycles and creates extra objects in memory.
- It also avoids compile-time checks, which should be avoided if possible.
Simple Why:
- Early on, it was difficult to avoid passing a value to an
object
parameter or non-generic collection.- NOTE: This has been mostly solved with generics and .NET maturity.
How
When passing values to an object parameter:
using System.Collections;
ArrayList x = new ArrayList();
int myInt = 10; // Int
x.Add(myInt); // Boxing Int -> Object
int y = (int) x[0]; // Unboxing Object -> Int Explicitly
In our debugger, we can see this the value -> reference -> value nastiness:
Console.WriteLine#
Simple Definition:
- Writes to the console & adds a newline.
- Basically
Console.Write
with a newline at the end.
Simple Why:
Console.WriteLine()
beatsConsole.Write()
as you'll usually want to add a return.- Allows platform agnostic newlines, since each OS uses different control characters. (1)
- MacOS only uses the
return
orcarriage return
character\r
, Linux only uses thenewline
orline feed
character\n
, and Windows uses BOTH\r\n
.
How
Input:
System.Console.WriteLine("Hello");
System.Console.WriteLine("World");
Output:
Hello
World
World
will have a newline at the end as well. There are a few ways to slam variables into a string, you should know all of them!
All 3 ways deliver this output:
Output:
Ed
Round 1: 2
Round 2: 3
Total: 5
Concatenation:
string name = "Ed";
int scoreOne = 2;
int scoreTwo = 3;
Console.WriteLine(name + "\nRound 1: " + scoreOne + "\nRound 2: " + scoreTwo + "\nTotal: " + (scoreOne + scoreTwo));
Composite Formatting:
string name = "Ed";
int scoreOne = 2;
int scoreTwo = 3;
Console.WriteLine("{0}\nRound 1: {1}\nRound 2: {2}\nTotal: {3}", name, scoreOne, scoreTwo, (scoreOne + scoreTwo));
string name = "Ed";
int scoreOne = 2;
int scoreTwo = 3;
Console.WriteLine($"{name}\nRound 1: {scoreOne}\nRound 2: {scoreTwo}\nTotal: {scoreOne + scoreTwo}");
String interpolation is usually the most expressive & shortest:
Look, just click this link and pay attention to this picture: