================================================================================ Basic record declaration ================================================================================ record F { int Age { get; init; } } -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) body: (declaration_list (property_declaration type: (predefined_type) name: (identifier) accessors: (accessor_list (accessor_declaration) (accessor_declaration)))))) ================================================================================ Basic record struct declaration ================================================================================ record struct F { int Age { get; init; } } -------------------------------------------------------------------------------- (compilation_unit (record_struct_declaration name: (identifier) body: (declaration_list (property_declaration type: (predefined_type) name: (identifier) accessors: (accessor_list (accessor_declaration) (accessor_declaration)))))) ================================================================================ Record class with optional `class` specification ================================================================================ record class F { int Age { get; init; } } -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) body: (declaration_list (property_declaration type: (predefined_type) name: (identifier) accessors: (accessor_list (accessor_declaration) (accessor_declaration)))))) ================================================================================ Record with a type parameter struct constraint ================================================================================ public record F where T:struct {} -------------------------------------------------------------------------------- (compilation_unit (record_declaration (modifier) name: (identifier) type_parameters: (type_parameter_list (type_parameter name: (identifier))) (type_parameter_constraints_clause target: (identifier) constraints: (type_parameter_constraint)) body: (declaration_list))) ================================================================================ Record with a type parameter class constraint ================================================================================ public record F where T:class {} -------------------------------------------------------------------------------- (compilation_unit (record_declaration (modifier) name: (identifier) type_parameters: (type_parameter_list (type_parameter name: (identifier))) (type_parameter_constraints_clause target: (identifier) constraints: (type_parameter_constraint)) body: (declaration_list))) ================================================================================ Record with type parameter new constraint ================================================================================ public record F where T: new() {} -------------------------------------------------------------------------------- (compilation_unit (record_declaration (modifier) name: (identifier) type_parameters: (type_parameter_list (type_parameter name: (identifier))) (type_parameter_constraints_clause target: (identifier) constraints: (type_parameter_constraint (constructor_constraint))) body: (declaration_list))) ================================================================================ Record with interface ================================================================================ public record A : ISomething { } -------------------------------------------------------------------------------- (compilation_unit (record_declaration (modifier) name: (identifier) bases: (base_list (identifier)) body: (declaration_list))) ================================================================================ Record with multiple type parameter constraints ================================================================================ [Nice] private record F where T1 : I1, I2, new() where T2 : I2 { } -------------------------------------------------------------------------------- (compilation_unit (record_declaration (attribute_list (attribute name: (identifier))) (modifier) name: (identifier) type_parameters: (type_parameter_list (type_parameter name: (identifier)) (type_parameter name: (identifier))) (type_parameter_constraints_clause target: (identifier) constraints: (type_parameter_constraint (type_constraint type: (identifier))) constraints: (type_parameter_constraint (type_constraint type: (identifier))) constraints: (type_parameter_constraint (constructor_constraint))) (type_parameter_constraints_clause target: (identifier) constraints: (type_parameter_constraint (type_constraint type: (identifier)))) body: (declaration_list))) ================================================================================ Record with constructor ================================================================================ record Person(string FirstName, string LastName); -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) parameters: (parameter_list (parameter type: (predefined_type) name: (identifier)) (parameter type: (predefined_type) name: (identifier))))) ================================================================================ Record inheritance with constructor overload ================================================================================ record Teacher(string FirstName, string LastName, string Subject) : Person(FirstName, LastName); -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) parameters: (parameter_list (parameter type: (predefined_type) name: (identifier)) (parameter type: (predefined_type) name: (identifier)) (parameter type: (predefined_type) name: (identifier))) bases: (base_list (primary_constructor_base_type type: (identifier) (argument_list (argument (identifier)) (argument (identifier))))))) ================================================================================ Record inheritance with constructor overload and interfaces ================================================================================ record Teacher(string FirstName, string LastName, string Subject) : Person(FirstName, LastName), Ns.I1, I2; -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) parameters: (parameter_list (parameter type: (predefined_type) name: (identifier)) (parameter type: (predefined_type) name: (identifier)) (parameter type: (predefined_type) name: (identifier))) bases: (base_list (primary_constructor_base_type type: (identifier) (argument_list (argument (identifier)) (argument (identifier)))) (qualified_name qualifier: (identifier) name: (identifier)) (identifier)))) ================================================================================ Record inheritance with generic base ================================================================================ record Teacher() : Entity(), I1; record A : System.IEquatable; -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) parameters: (parameter_list) bases: (base_list (primary_constructor_base_type type: (generic_name name: (identifier) type_arguments: (type_argument_list (identifier))) (argument_list)) (identifier))) (record_declaration name: (identifier) bases: (base_list (qualified_name qualifier: (identifier) name: (generic_name name: (identifier) type_arguments: (type_argument_list (identifier))))))) ================================================================================ Record types can end with a semicolon ================================================================================ public record Person { }; public record struct Person2 { }; -------------------------------------------------------------------------------- (compilation_unit (record_declaration (modifier) name: (identifier) body: (declaration_list)) (record_struct_declaration (modifier) name: (identifier) body: (declaration_list))) ================================================================================ Record types can seal ToString() ================================================================================ record A { public sealed override string ToString(){ return ""; } } -------------------------------------------------------------------------------- (compilation_unit (record_declaration name: (identifier) body: (declaration_list (method_declaration (modifier) (modifier) (modifier) type: (predefined_type) name: (identifier) parameters: (parameter_list) body: (block (return_statement (string_literal))))))) ================================================================================ With expression typical basic form ================================================================================ void A() { var newFriend = friend with { LastName = "Edwards" }; } -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_function_statement type: (predefined_type) name: (identifier) parameters: (parameter_list) body: (block (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (with_expression (identifier) (with_initializer_expression (simple_assignment_expression (identifier) (string_literal (string_literal_fragment))))))))))))) ================================================================================ With expression using expressions ================================================================================ void A() { var friend = GetAFriend() with { ForeName = RandomFirstName(), LastName = RandomLastName() }; } -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_function_statement type: (predefined_type) name: (identifier) parameters: (parameter_list) body: (block (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (with_expression (invocation_expression function: (identifier) arguments: (argument_list)) (with_initializer_expression (simple_assignment_expression (identifier) (invocation_expression function: (identifier) arguments: (argument_list))) (simple_assignment_expression (identifier) (invocation_expression function: (identifier) arguments: (argument_list))))))))))))) ================================================================================ Precedence between with and cast ================================================================================ var x = (Point) p1 with {X = 3}; -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (with_expression (cast_expression type: (identifier) value: (identifier)) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal)))))))))) ================================================================================ Precedence between with and switch ================================================================================ var x = p1 with {X = 3} switch { _ => 3 }; -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (switch_expression (with_expression (identifier) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal)))) (switch_expression_arm (discard) (integer_literal))))))))) ================================================================================ Precedence between with and equals ================================================================================ var x = p1 with {X = 3} == p1 with {X = 4}; -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (binary_expression left: (with_expression (identifier) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal)))) right: (with_expression (identifier) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal))))))))))) ================================================================================ Associativity of with expression ================================================================================ var x = p1 with {X = 3} with {X = 4} with {X = 5}; -------------------------------------------------------------------------------- (compilation_unit (global_statement (local_declaration_statement (variable_declaration type: (implicit_type) (variable_declarator name: (identifier) (equals_value_clause (with_expression (with_expression (with_expression (identifier) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal)))) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal)))) (with_initializer_expression (simple_assignment_expression (identifier) (integer_literal))))))))))