0

Given the following methods:

internal static void BasicLog(
    this int logData)
    => CreateSystemLog(Type.BasicLog, logData.ToString());

internal static void BasicLog(
    this long logData)
    => CreateSystemLog(Type.BasicLog, logData.ToString();

internal static void BasicLog(
    this short logData)
    => CreateSystemLog(Type.BasicLog, logData.ToString());

Is there any way to condense these methods into one method? EG, a method that takes an int, long or short to avoid this repeating code.

Tom Gullen
  • 61,249
  • 84
  • 283
  • 456
  • You are creating extension methods for different types, you can not combine them in one. If you it is just a static method you can create a generic method `internal static void BasicLog(T logdata)` – Chetan Oct 04 '22 at 10:47
  • With current C# language versions, unfortunately not. The best you could do is to use generics to restrict the method parameter to value types (that includes any primitive value types as well as structs), but not to int/long/short specifically... –  Oct 04 '22 at 10:47
  • No there isn't. You can write a method that takes any type but there's no way to limit it to just those three types. .NET 7 has an INumber interface or the like, but that would still include other numeric types. I don't think there's an interface for just whole number types and, even if there was, that would probably still include byte. – jmcilhinney Oct 04 '22 at 10:48
  • As others have mentioned, you could potentially use generics with restrictions. This may help: https://stackoverflow.com/questions/3329576/generic-constraint-to-match-numeric-types – sr28 Oct 04 '22 at 10:49
  • 1
    I can't test now but I think those other types can be implicitly converted to long, so is it maybe possible to just write the method for long and call it on the other types? – jmcilhinney Oct 04 '22 at 10:51
  • Is there a reason you want to specifically restrict it to those types? Since you're calling `ToString` on everything it seems there's no logic behind only supporting those types, so @Chetan's example should work. – Xerillio Oct 04 '22 at 10:53

1 Answers1

1

AFAIK currently there is no way to restrict extension method to accept only int, short or long . If you are ok with any type being passed to the method then you can just use generics:

internal static void BasicLog<T>(
    this T logData)
    => CreateSystemLog(Type.BasicLog, logData.ToString());

Possibly constraining it to struct or for .NET 7 one of the generic math types/interfaces if you want to reduce the number of possibilities.

If you are ok with moving from extension methods - then you can use OneOf:

public static class Helpers
{
    public static void BasicLog(OneOf<int, short, long> logData)
        => Console.WriteLine(logData.Match(i => i.ToString(), i => i.ToString(), i => i.ToString()))
}

Which uses implicit conversions for such calls (you can skip Helpers by adding using static Helpers;):

Helpers.BasicLog(1L);
Helpers.BasicLog(1);
Helpers.BasicLog((short)1);

Or leverage the existing conversions from int and short to long and remove all methods except the long (though it will accept everything implicitly convertible to long, also you can keep this, but it will work as extension method only for long's, everything else will require explicit cast):

internal static void BasicLog(long logData)
    => CreateSystemLog(Type.BasicLog, logData.ToString();
Guru Stron
  • 102,774
  • 10
  • 95
  • 132