# Records

Records 是一种全新的简化的 C# classstruct 的形式。

class Point : IEquatable<Point>
{
public readonly double X;
public readonly double Y;

public Point(double X, double Y)
{
this.X = X;
this.Y = Y;
}

public static bool operator==(Point left, Point right) { ... }

public bool Equals(Point other) { ... }
public override bool Equals(object other) { ... }
public override int GetHashCode() { ... }
public void Deconstruct(out double x, out double y) { ... }
}


data class Point(double X, double Y);


var pointA = new Point(3, 5);
var pointB = pointA with { Y = 7 };
var pointC = new Point(3, 7);

// 当 Y = 5 时为 X，否则为 Y
var result = pointB switch
{
(var first, 5) => first,
(_, var second) => second
};

// true
Console.WriteLine(pointB == pointC);


sealed data class Point3D(double X, double Y, double Z) : Point(X, Y);


data class Point { double X; double Y };
var point = new Point { X = 5, Y = 6 };


# Discriminated Unions

Discriminated unions 又叫做 enum class，这是一种全新的类型声明方式，顾名思义，是类型的 “枚举”。

enum class Shape
{
Retangle(double Width, double Height);
Triangle(double Bottom, double Height);
Nothing;
}


var circle = new Circle(5);
var rec = new Rectangle(3, 4);

if (rec is Retangle(_, 4))
{
Console.WriteLine("这不是我想要的矩形");
}

var height = GetHeight(rec);

double GetHeight(Shape shape)
=> shape switch
{
Retangle(_, height) => height,
Triangle(_, height) => height,
_ => throw new NotSupportedException()
};


enum class Option<T>
{
Some(T value);
None;
}

var x = Some(5);
// Option<never>
var y = None;

void Foo(Option<T> value)
{
var bar = value switch
{
Some(var x) => x,
None => throw new NullReferenceException()
};
}


# Union and Intersection Types

public type SignedNumber = short | int | long | float | double | decimal;
public type ResultModel<T> = DataModel<T> | ErrorModel;


public class ResultModel<T>
{
public string Message { get; set; }
public int Code { get; set; }
public T Data { get; set; }
}


public async ValueTask<DataModel | ErrorModel> SomeApi()
{
if (...) return new DataModel(...);
return new ErrorModel(...);
}


interface IA { ... }
interface IB { ... }
interface IAB : IA, IB { }

void Foo(IAB obj) { ... }


void Foo(IA & IB obj) { ... }


type IAB = IA & IB;


# Bottom Type

Bottom type 是一种特殊的类型 nevernever 类型是任何类型的子类，因此不存在该类型的子类。一个 never 类型的什么都不表示。

Union types 带来一个问题，就是我们有时候需要表达这个东西什么都不是，那么 never 将是一个非常合适的选择：

type Foo = Bar | Baz | never;


void | never Foo(int x)
{
if (x > 5) return;
return never;
}

void Main()
{
Foo(6);
Console.WriteLine(1);
Foo(4);
Console.WriteLine(2);
}


# Concepts

Concepts 又叫做 type classes、traits，这个特性做到可以在不修改原有类型的基础上，为类型实现接口。

concept Monoid<T>
{
// 加函数
T Append(this T x, T y);
// 零属性
static T Zero { get; }
}


instance IntMonoid : Monoid<int>
{
int Append(this int x, int y) => x + y;
static int Zero => 0;
}


public T Sum<T, inferred M>(T[] array) where M : Monoid<T>
{
T acc = M.Zero;
foreach (var i in array) acc = acc.Append(i);
return acc;
}


# Higher Kinded Polymorphism

Higher kinded polymorphism，又叫做 templated template，或者 generics on generics，这是一种高阶的多态。

void Foo<T>() where T : <>, ICollection<>, new();


T<X> To<T, X>(this IEnumerable<X> xs) where T : <>, ICollection<>, new()
{
var result = new T<X>();
foreach (var x in xs) result.Add(x);
return result;
}


# Simple Programs

namespace Foo
{
class Bar
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello world!");
}
}
}


await Task.Delay(1000);
Console.WriteLine("Hello world!");


# Expression Blocks

Func<int, int, bool> greaterThan = (a, b) => if (a > b) a else b;

// true
greaterThan(5, 4);


# 后记

posted @ 2020-02-29 20:42  hez2010  阅读(5542)  评论(39编辑  收藏  举报