I wanted to create a number of "NanoValue" struct Ids which are a long representation of a value multiplied by 1E9.
So I started with this:
public readonly partial record struct SomeNanoValue(long Value) : IStructId<long>
{
}
Then, I wanted to be able to explicitly convert it to a decimal with named methods (and certainly not an implicit cast).
So I added this interface:
public interface INanoValueConvertsToDecimal : IStructId<long>
{
decimal ToDecimal();
static abstract INanoValueConvertsToDecimal FromDecimal(decimal value);
}
But I just wasn't able to get the static abstract working in a template. In the end I dropped the template idea and put an unsatisfactory default implementation on the interface itself:
public readonly partial record struct SomeNanoValue(long Value) : IStructId<long>, INanoValueConvertsToDecimal<SomeNanoValue>
{
}
public interface INanoValueConvertsToDecimal<T> : IStructId<long> where T : INanoValueConvertsToDecimal<T>, INewable<T, long>
{
decimal ToDecimal() => Value / 1E9M;
static T FromDecimal(decimal value) => T.New((long)(value * 1E9M));
}
It's unsatisfactory because I wanted to use
var x = SomeNanoValue.FromDecimal(21M); // doesn't compile
// instead of
var y = INanoValueConvertsToDecimal<SomeNanoValue>.FromDecimal(21M); // the best I've got :(


I wanted to create a number of "NanoValue" struct Ids which are a
longrepresentation of a value multiplied by1E9.So I started with this:
Then, I wanted to be able to explicitly convert it to a
decimalwith named methods (and certainly not an implicit cast).So I added this interface:
But I just wasn't able to get the static abstract working in a template. In the end I dropped the template idea and put an unsatisfactory default implementation on the interface itself:
It's unsatisfactory because I wanted to use