RemObjects C# adds a few features to the standard C# language to make it fit better on all the platforms it supports. We try to keep these extensions to a minimum, and tasteful within the design aesthetics of the C# language.
Where additional keywords are needed, we follow the C/C++/C# convention of prefixing these with two underscores ("
__") to avoid conflict with future changes to the C# spec.
Multi-Part Method and Constructor Names
In order to fit in well with the API conventions on the Cocoa platform, RemObjects C# adds support for multi-part method names — essentially the ability for a method's name to be split into separate parts, each followed by a distinct parameter. This feature is available on all platforms, and described in more detail in the Multi-part method names topic.
Similar to the "nullable types" feature in standard C#, reference type variables can be adorned byf the
! operator to mark them as "not nullable". See the Nullability topic in the Language Concepts section for more details, and Non-Nullable Types for a more explicit discussion of the C# syntax (which mirrors nullable types in our Java dialect, Iodine).
Functions can be marked with the
__inline keyword to cause them to be inlined at the call site instead of being generated as separate functions in the executable. See the Inline Functions topic for more details.
Labeled Loop Statements
Labeled Loop Statements allow you more control when writing nested loops, including the ability to
continue an outer loop from inside a nested one.
Similar to Swift, RemObjects C# supports using a Trailing Closures syntax when calling methods who's last parameter is a closure. This can make for code that looks cleaner and more easy to read than embedding the closure as last parameter within the parentheses.
Await for Closure Callbacks
await keyword works not only with "async/await"-style APIs but also with methods that expect a trailing callback parameter.
RemObjects C# adds the
__unretained type modifiers to control how the lifetime of Automatic Reference Counted objects is handled on Cocoa. The modifiers are described in the Storage Modifiers topic. The
using __autoreleasepool can be used to manually control ARC auto-release pools.
__selector() can be used to create a selector instance on Cocoa, for use in functions that take such a selector for callback purposes, and for dynamic dispatch of method calls in the Objective-C runtime environment. This is described here.
RemObjects C# also has full support for a feature called Mapped Types, which are inlined types useful to create cross-platform wrappers with zero overhead. While you won't often implement your own mapped types, you will likely use existing ones, for example from the Elements RTL library.
Extensions Types can be used to expand an existing type with new methods or properties.
Inheritance for Structs
In RemObjects C#,
structs can specify an ancestor, allowing a newly declared struct to inherit the fields and methods of its base struct. Unlike classes, structs are not polymorphic, and members cannot be virtual or overriden.
Aspects are special attributes that influence how the compiler emits the final executable. In RemObjects C#, they use attributes syntax and the optional
__aspect: attribute prefix. Aspects are covered in more detail in their own section, including how to use them and how to create your own.
Class Contracts allow code to become self-testing, with Pre- and Post-Conditions for methods and type-wide Invariants.
Mostly to fit in better with Cocoal and Island, but available on all platforms, RemObjects C# allows you to both call and define global methods (functions) and variables that are not contained within a class.
Public/Non-Local Type Aliases
Standard C# allows the declaration of local type aliases with the syntax
using keyword, but these aliases are confined to be visible in the current file only. RemObjects C# allows the annotation of this syntax with the
public keyword to define global/public aliases that will be visible anyehwere the containing namespace is in scope.
public using Menu = Foundation.NSMenu;