When calling methods with out parameters, you can declare variables inline
int.TryParse ("100", out int output);
If you don't need the value of an out parameter, you can discard it with an underscore
if (int.TryParse (numberString, out _))
{
Console.Writeline("Valid number");
}
We can now test for type and introduce a variable at the same time
object mydata = 100;
if(mydata is int mynumber)
{
mynumber++;
}
We can now switch on *type*
void Main()
{
Demo (new TextBox());
Demo (new ComboBox());
Demo (null);
}
void Demo (Control control)
{
switch (control)
{
case TextBox t: // Switch on type
//Your code here
break;
case ComboBox c:
//Your code here
break;
case null: // The 'null' literal is legal here
//Your code here
break;
default:
//Your code here
break;
}
}
Tuple is a data structure that contains a sequence of elements of different data types. It can be used where you want to have a data structure to hold an object with properties, but you don't want to create a separate type for it. The advantages include a simpler syntax, rules for conversions based on number (referred to as cardinality) and types of elements, and consistent rules for copies, equality tests, and assignments.
var tuple = ("three", 3);
Console.WriteLine(tuple.Item1);
Console.WriteLine(tuple.Item2);
//assigning with explicit typing.
(string, int) tuple2 = tuple;
//named tuples.
var namedTuple = (word: "three", number: 3);
Console.WriteLine(namedTuple.word);
Console.WriteLine(namedTuple.number);
With tuples, you can easily write a method that returns more than one value
(string, DateTime) Foo() => ("Now", DateTime.Now);
(string name, DateTime time) NamedFoo() => ("Now", DateTime.Now);
// You can discard a tuple member with an underscore:
var (s, _) = Foo();
You can now declare a function within a function.
We can't do method overloading with local functions.
Local functions are also allowed inside iterators.
public int Calculate(int x)
{
return Sum(x).sum;
(int sum, int count) Sum(int i)
{
return (100, 1);
}
}
C# 6 introduced expression-bodied members for member functions, and read-only properties.
C# 7.0 expands the allowed members that can be implemented as expressions. In C# 7.0, you can implement constructors, finalizers, and get and set accessors on properties and indexers.
// Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;
// Expression-bodied finalizer
~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!");
private string label;
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value ?? "Default label";
}
You can now throw expressions in expressions clauses.
public string Foo() => throw new NotImplementedException();
string result = new Random().Next(2) == 0 ? "Good" : throw new Exception ("Bad");