Is there a way to create a custom integral type in C# with conversion checking at compile time, using Visual Studio 2022?
Problem Description:
I am using Visual Studio 2022, and would like to create various types of data which need to be constrained to certain values. Specifically, I’m making types for liters, pH, and other stuff related to liquids.
To do this, I was hoping to create custom types that would be checked as I typed my code in VS2022, similar to when you try to use a negative integer where C# expects a uint, or trying (uint)-1
giving you an error.
I’ve tried to create a struct which casts those values, but that’s only checked at run-time, meaning that I’ll have to first run my code before a cast from a negative value is caught and an error is shown.
The following struct is not statically checked for conversion.
public struct liters {
private readonly double v;
public liters(double v) {
if (v is < 0) { throw new ArgumentOutOfRangeException(nameof(v)); }
this.v = v;
}
public static implicit operator liters(double v) { return new liters(v); }
public static implicit operator double(liters liters) { return liters.v; }
}
Solution – 1
You need to look into .NET compiler platform (Roslyn) and custom code analyzers. This is the main tool for custom compile time checks, though it can be not that trivial to write one.
In your case you can try writing analyzer for cast expressions which will check the target type and literal from which the cast is happening.
Some useful links:
- Overview of .NET source code analysis (there are links to some 3rd party code analyzers, like
StyleCop.Analyzers
which you can take a look at for inspiration) - sharplab.io which allows to view syntax trees which can be a huge help when writing your own analyzer
- My analyzer for my pet project if you want some entry level stuff =)