Skip to content

Instantly share code, notes, and snippets.

@tuannguyenssu
Created July 20, 2019 14:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tuannguyenssu/2343b9e4fd42c86ccf29269442a838fe to your computer and use it in GitHub Desktop.
Save tuannguyenssu/2343b9e4fd42c86ccf29269442a838fe to your computer and use it in GitHub Desktop.
//--------------------------------------------------------------------------------------
// C# 8.0 Features - Các tính năng nổi bật trên phiên bản C# 8.0
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// 1. Indices and Range
//--------------------------------------------------------------------------------------
var people = new string[] { "Jane", "Jean", "Grey", "Marcus", "Theophilus", "Keje" };
//--------------------------------------------------------------------------------------
// Lấy ra các phần tử trong mảng
var all = people[..]; // Lấy ra tất cả các phần tử và đưa vào một biến mới
var firstFour = people[..4]; // Lấy ra 4 phần tử đầu tiên "Jane", "Jean", "Grey", and "Marcus"
var lastTwo = people[4..]; // Lấy ra 2 phần tử cuối cùng "Theophilus" and "Keje"
//--------------------------------------------------------------------------------------
// Lấy ra các phần tử với khai báo khoảng range riêng
Range firstFourRange = ..4
var firstFour = people[firstFourRange]; // Lấy ra 4 phần tử đầu tiên "Jane", "Jean", "Grey", and "Marcus"
Range lastTwoElement = ^2..
var lastTwo = people[lastTwoElement] // Lấy ra 2 phần tử cuối cùng "Theophilus" and "Keje"
Index lastIndex = ^1; // Khai báo chỉ số
string value = people[lastIndex]; // Lấy giá trị theo chỉ số
//--------------------------------------------------------------------------------------
// 2. Static Local Functions
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Khai báo hàm bên trong hàm
public string MethodWithLocalFunction()
{
string firstname = "Tuan";
string lastname = "Nguyen";
return LocalFunction();
string LocalFunction() => firstname + " - " + lastname;
}
//--------------------------------------------------------------------------------------
// Khai báo hàm static bên trong hàm
public string MethodWithLocalFunction()
{
string first = "Nguyen";
string last = "Tuan";
return LocalFunction(first, last);
static string LocalFunction(string firstname, string lastname) => firstname + " - " + lastname;
}
//--------------------------------------------------------------------------------------
// 3. Using Declaration
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Với các phiên bản trước đó
void ReadFile(string path)
{
// Lồng nhiều using rất bất tiện và khó đọc
using (FileStream fs = File.OpenRead(path)) // using declaration
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
}
}
//--------------------------------------------------------------------------------------
// Khai báo using tiện lợi hơn với C# 8
void ReadFile(string path)
{
using FileStream fs = File.OpenRead(path); // using declaration
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
// fs is disposed here
}
//--------------------------------------------------------------------------------------
// 4. Readonly Members
//--------------------------------------------------------------------------------------
public struct Point
{
public double X { get; set; }
public double Y { get; set; }
public double Distance => Math.Sqrt(X * X + Y * Y);
public override string ToString() =>
$"({X}, {Y}) is {Distance} from the origin";
}
//--------------------------------------------------------------------------------------
// Khai báo readonly
public readonly double Distance => Math.Sqrt(X * X + Y * Y);
public readonly override string ToString() => $"({X}, {Y}) is {Distance} from the origin";
public readonly void Translate(int xOffset, int yOffset)
{
X += xOffset;
Y += yOffset;
}
//--------------------------------------------------------------------------------------
// 5. Pattern Matching - Switch Expressions
//--------------------------------------------------------------------------------------
public enum Rainbow
{
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}
//--------------------------------------------------------------------------------------
// Các phiên bản trước
public static RGBColor FromRainbowClassic(Rainbow colorBand)
{
switch (colorBand)
{
case Rainbow.Red:
return new RGBColor(0xFF, 0x00, 0x00);
case Rainbow.Orange:
return new RGBColor(0xFF, 0x7F, 0x00);
case Rainbow.Yellow:
return new RGBColor(0xFF, 0xFF, 0x00);
case Rainbow.Green:
return new RGBColor(0x00, 0xFF, 0x00);
case Rainbow.Blue:
return new RGBColor(0x00, 0x00, 0xFF);
case Rainbow.Indigo:
return new RGBColor(0x4B, 0x00, 0x82);
case Rainbow.Violet:
return new RGBColor(0x94, 0x00, 0xD3);
default:
throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
};
}
//--------------------------------------------------------------------------------------
// C# 8 dùng switch trong câu lệnh
public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
Rainbow.Green => new RGBColor(0x00, 0xFF, 0x00),
Rainbow.Blue => new RGBColor(0x00, 0x00, 0xFF),
Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};
//--------------------------------------------------------------------------------------
// Dùng switch kết hợp với property (Property pattern)
public static decimal ComputeSalesTax(Address location, decimal salePrice) =>
location switch
{
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.75M,
{ State: "MI" } => salePrice * 0.05M,
// other cases removed for brevity...
_ => 0M
};
//--------------------------------------------------------------------------------------
// Dùng switch kết hợp với Tuple (Tuple pattern)
public static string RockPaperScissors(string first, string second)
=> (first, second) switch
{
("rock", "paper") => "rock is covered by paper. Paper wins.",
("rock", "scissors") => "rock breaks scissors. Rock wins.",
("paper", "rock") => "paper covers rock. Paper wins.",
("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
("scissors", "rock") => "scissors is broken by rock. Rock wins.",
("scissors", "paper") => "scissors cuts paper. Scissors wins.",
(_, _) => "tie"
};
//--------------------------------------------------------------------------------------
// Positonal pattern
public enum Quadrant
{
Unknown,
Origin,
One,
Two,
Three,
Four,
OnBorder
}
static Quadrant GetQuadrant(Point point) => point switch
{
(0, 0) => Quadrant.Origin,
var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
_ => Quadrant.Unknown
};
//--------------------------------------------------------------------------------------
// 6. Asynchronous streams
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Tạo và sử dụng stream bất đồng bộ
public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}
await foreach (var number in GenerateSequence())
{
Console.WriteLine(number);
}
//--------------------------------------------------------------------------------------
// 7. Nullable References
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
class Student
{
public string FirstName {get; set;}
public string LastName {get; set;}
public Student(string firstName)
{
FirstName = firstName;
}
}
public void PrintInfo(Student student)
{
return $"{student.FirstName} {student.LastName}"
}
var student = new Student("Tuan");
// Dính lỗi NullReferenceException do LastName không được khởi tạo
PrintInfo(student);
// C#8 giúp ta có thể detect sớm vấn đề này bằng cách sử dụng #nullable enabled
#nullable enabled
class Student
{
public string FirstName {get; set;}
public string LastName {get; set;}
public Student(string firstName)
{
FirstName = firstName;
}
}
public void PrintInfo(Student student)
{
// Sẽ có cảnh báo ở dòng này
return $"{student.FirstName} {student.LastName}"
}
// Sửa lại bằng cách kiểm tra null
public void PrintInfo(Student student)
{
if(student != null)
return $"{student.FirstName} {student.LastName}"
else
return $"{student.FirstName}"
}
//--------------------------------------------------------------------------------------
// 8. Default Interface Member
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Khai báo interface với default implementation
interface ILogger
{
void Log(LogLevel level, string message);
void Log(Exception ex) => Log(LogLevel.Error, ex.ToString());
}
public static void LogException(ConsoleLogger logger, Exception ex)
{
ILogger ilogger = logger; // Converting to interface
ilogger.Log(ex); // Calling new Log overload
}
//--------------------------------------------------------------------------------------
// 9. Disposable ref structs
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Khai báo ref struct với hàm hủy
ref struct Book
{
public void Dispose()
{
}
}
using var book = new Book();
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment