See Tips for golfing in C#

Declaring multiple variables

It is possible to declare multiple variables of the same type at once.

int a=0;int b;int c=123;int d=c;
int a=0,b,c=123,d=c;

Sometimes it is also possible to declare multiple variables of different types at once using the dynamic type.

int a=0;string s="";
dynamic a=0,s="";

dynamic variables can also change types:

dynamic t="abc";
Console.WriteLine(t=2*3);

For long type names one can also use the var keyword, though this requires assigning to the variable immediatly and it is not possible to declare multiple variables at once this way.

string s="";
var s="";

The different for loop sections

The initialiazier section can be used to execute multiple statements (not necessarily variable assignments), but does not allow for multiple variable declaration statements.

int n=1;
for(Console.Write(n),n=23,Console.WriteLine(n);false;);

When the condition section is left empty it evaluates to true.

int n=0;
for(;;n++)if(n>9)break;
Console.Write(n);

This can also often be used to make a program which loops over the arguments and then exits by crashing.

for(int i=0;;)Console.WriteLine(args[i++]);

Like the initializer section, the iterator section may contain multiple statements. This can sometimes be used to save a couple bytes.

for(int n=0,s=0;n<10;n++){s+=n;Console.WriteLine(n+": "+s);}
for(int n=0,s=0;n<10;Console.WriteLine(n+": "+s),n++)s+=n;

Shorter foreach

LINQ is imported by default, which allows for something shorter than a regular foreach loop in many cases if all you need is a single statement in the loop.

foreach(var a in args)Console.WriteLine(a);
args.Any(a=>Console.WriteLine(a)is GC);

Other LINQ functions can be used in some cases aswell, for example summing up elements:

int s=0;foreach(var a in args)s+=int.Parse(a);
int s=args.Sum(a=>int.Parse(a));
int s=args.Sum(int.Parse);

Ternary operator

The ternary operator can often be used to replace if statements:

if(n<1)n=-n;
n=n<1?-n:n;

Lambda expressions

Lambda expressions can be used to shorten function definitions if they only contain a single statement:

int f(int n){return n<2?1:n*f(n-1);}
int f(int n)=>n<2?1:n*f(n-1);

Characters and scientific notation for constants

Large numbers can often be replaced by characters or using scientific notation. Note that the latter is are of type double/float

for(int i=0;i<1000;i++)Console.WriteLine(i);
for(int i=0;i<'Ϩ';i++)Console.WriteLine(i);
for(int i=0;i<1e3;i++)Console.WriteLine(i);

var d=0.00035;
var d=35e-5;

Strings for lookup tables

It is often possible to use strings for lookup tables:

foreach(int n in new[]{65,75,100,500})Console.WriteLine(n);
foreach(int n in"AKdǴ")Console.WriteLine(n);

Ranges

Ranges can be used to slice arrays and strings, aswell as access elements from the back with ^:

string s="Hello, World!\n";
Console.Write(s[5..]+s[..5]+s[^2..]+s[3..7]);

String literals

There are different types of string literals:

// quoted string literal
string s="Hello,\n\"World\"!";

// verbatim string literal; can often be used to save characters when a string contains multiple linebreaks
string s=@"Hello,
""World""!";

// raw string literal
string s="""Hello,
"World"!""";

String formatting

String interpolation can often be used to format strings:

Console.Write("{0,10:b8}",7*7);
Console.Write($"{7*7,10:b8}");

More on the different format specifiers: composite-formatting

The ; specifier can be used to print different values based on whether a number is positive, negative, or zero:

for(int i=-1;i<=1;i++)Console.Write($"{i:'Positive';'Negative';'Zero'}\n");

Instantiating collections and arrays

Here are some comparisons between different ways to instantiate collections and arrays:

List<int>l=new List<int>();
var l=new List<int>();
List<int>l=new();
List<int>l=[];

int[]a=new int[]{1,2,3};
var a=new int[]{1,2,3};
int[]a=new[]{1,2,3};
var a=new[]{1,2,3};
int[]a={1,2,3};
int[]a=[1,2,3];

Temporary variables in a single statement

These three variations do the same, though the second one allows you to access the result of c-48 outside of the function s:

int s(int c){int n=c-48;return n*n;}
int n;int s(int c)=>(n=c-48)*n;
int s(int c)=>c-48is{}n?n*n:0;