Monday, June 11, 2018

Record definition

You can see a record as a simple class, without inheritance.
As a class is living on the heap, a record is living on the stack - making it a limited, but simpler and faster entity than a class. Just as classes, records can have constructors, finalizers, methods, fields, properties and constants, but a record can not be disposable as it can not implement interfaces.

Record visibility
The most simple class definition you can write:
The code above defines the record MyRecord.
The visibility of the record is not defined and will be Unit (see Visibility modifiers).

We can make the record public accessible by adding the visibility modifier Public:

Record modifiers
With a record modifier you give a hint to the compiler of how to compile this record:
partialA partial record definition is a record that can be defined over more than one code file.
readonlyWhen a record is marked readonly, all variables and properties are readonly. This means that they can only be set from within a constructor of the record.

Example of the usage of a class modifier:

Record constructors
When a record is instantiated, the constructor is executed. A constructor is a special kind of method that initializes the record (makes it ready for use) and is the only place where you can initialize read only fields.
A record can have more than one constructor .

To define a constructor, you use the constructor keyword:

In the example above, two constructors are added to the record, one without and one with parameters. You can add as much constructors as you want / need to the record.

Record destructors or finalizers
When a record is being destroyed (GC or reference counting), the finalizer is executed to clean the state of the instance.
A finalizer is always executed from an unknown thread - so the code should be thread safe!
The code of the finalizer is a last resort to clean up - it should already been done before the finalizer executes; with the use of the dispose pattern (.Net or Java only) or within the state handling of the record code.
A finalizer is defined with the Finalizer keyword:

A record can only have one finalizer and the finalizer is a method without any parameters. The implementation:

Interface inheritance
Interface inheritance is only available for .Net and Java - Other platforms do not support this.

A record can inherit from multiple interfaces - all of those interfaces have to be implemented (unless the interface has a default implementation, in that case the interface implementation is not mandatory).
The syntax to inherit from an interface is exactly the same as the syntax to inherit from a base class. Multiple interfaces to inherit from are separated by comma's.
To use the interface, we have to implement all methods and properties within the interface (in this case only the method Dispose):
When you implement more interfaces that have conflicting names, or you have reason to use another name than the standard name, you can use another name and the implements modifier to tell the compiler which interface is being implemented:

The implementation methods do not have to be public - they can also be private (or any other visibility), but as soon as you cast the object to the interface, the interface methods will be public and the methods will have their original names.

Inline arrays
To use this you need the UnSafe option - otherwise this won't compile.
A record is living on the stack, but reference to arrays are still pointers that point to a location on the heap where the object is stored. For use with P/Invoke it might be needed to inline an array, so it will be within the record on the stack.

No comments:

Post a Comment