Interoperability in .NET
This article was originally published 21st July 2020 on Linkedin
Adam Parker, Software Consultant at Opencast Software and have developed using .NET most of their career.
What is interop?
Allows you to take advantage of existing investments in unmanaged code and where code that runs under the control of the Common Language Runtime which is managed code and anything that runs outside the CLR is called unmanaged code. .NET Language interoperability allows other libraries from other languages in your project e.g. C# in VB, F# in C#, and other .NET Framework combinations.
Visual Basic, C# & F#
They share many common features such as classes, functions you can use libraries written in any .NET languages in other languages. But what about F# which has discriminated unions, options, higher order functions, modules, records, and sequences.
Things that work well in F#
Namespaces allow using statements just like C# namespaces. Modules expose themselves as Static Classes in C#. Values are exposed as static fields on a Class and Records generate a read-only class with only a full parameter Constructor when used with C# - these act as data containers and immutable but must provide all the values when used. Arrays work as expected in C#, Sequences get exposed as an IEnumerable. Functions will work in C# if they do not accept other functions as parameters. If Discriminated Unions only have numbers these compile to enums in C# or if Discriminated Unions use types, then this will create an Abstract Class which has methods for creating sub-types. Unit if a function returns Unit this compiles down to a function that is void, if used as a parameter it uses null.
Things that do not work so well in F#
Lists in F# are different to C# lists, you can import Fsharp.core package to work with the FsharpList<T> that's returned or you can use the IReadonlyCollection if you don't want to import the F# Code library. Discriminated Unions if you do not provide a type they do not work as well so need to match on the Tags for these values when being used in C# but if provide values in them this will result in an Enum. Options allow you to get the value and work as expected - this is special type to indicate it has something or not, however when you return an Option in F# and is returned is a nullable value - when you return None from F# this is a null in C#.
Things that should work
If a function takes another function, we have problems, as a FSharpFunc is created when used from C# and this is where the lambda can be used instead so have to use the Fsharp.core package to use this.
What is the point?
You can use VB and C# together using libraries or can even use F# libraries both in C# and VB. Can have a functional core and an imperative shell. Functional programming makes an invalid state difficult to create where everything is immutable and have an ASP.NET C# application using this core.