2
\$\begingroup\$

I'm retrieving the operating system platform with .NET Core with system.runtime.interopservices

I have created the code below and was wondering if there was any other way that I could improve it since I haven't been able to get a switch statement to work in the OperatingSystem class.

/// <summary>
/// Operating System Class
/// For Retrieving The OS
/// Platform.
/// AE : 9/08/2018
/// </summary>
class OperatingSystem
{
    /// <summary>
    /// Operating System Platforms.
    /// </summary>
    public enum OSPlatform
    {
        Windows,
        OSX,
        Linux,
        Not_Supported
    }

    /// <summary>
    /// Return Operating System
    /// </summary>
    public static OSPlatform GetPlatform
    {
        // Switch Statement Not Compatitable
        get
        {
            if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
            {
                return OSPlatform.Windows;
            }
            else if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX))
            {
                return OSPlatform.OSX;
            }
            else if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux))
            {
                return OSPlatform.Linux;
            }
            else
            {
                return OSPlatform.Not_Supported;
            }
        }
    }
}

The class is being called like this,

static void Main()
{
    switch (OperatingSystem.GetPlatform)
    {
        case OperatingSystem.OSPlatform.Windows:
            Console.WriteLine("Goto Windows Class");
            break;
        case OperatingSystem.OSPlatform.OSX:
            Console.WriteLine("Goto OSX Class");
            break;
        case OperatingSystem.OSPlatform.Linux:
            Console.WriteLine("Goto Linux Class");
            break;
        default:
            Console.WriteLine("OS Not Supported");
            break;
        }
        Console.ReadKey();
    }
\$\endgroup\$
6
  • \$\begingroup\$ I have a question: why have you created another enum that is virtually exactly the same as the core's one instead of using the original one? \$\endgroup\$ – t3chb0t Aug 9 '18 at 9:21
  • \$\begingroup\$ because its not a constant value \$\endgroup\$ – AndrewE Aug 9 '18 at 9:22
  • \$\begingroup\$ @t3chb0t also from what I can see OSPlatform is a struct and not an enum. \$\endgroup\$ – AndrewE Aug 9 '18 at 9:27
  • \$\begingroup\$ So you need a constant value? Could you specify your use case in more detail? Is this only because you like switches? I find it's a bad idea to duplicate those values without a very good reason. \$\endgroup\$ – t3chb0t Aug 9 '18 at 9:49
  • \$\begingroup\$ yeah it just comes down to me preferring switch es over if's once they get past a certian amount of uses and are too long \$\endgroup\$ – AndrewE Aug 9 '18 at 9:51
3
\$\begingroup\$

Review

  • Don't use underscores in enum values NotSupported
  • The enum value with integer value 0 represents its default value; I would make this NotSupported in order to avoid some bias
  • GetPlatform is a method name; prefer Platform as property name
  • Since the platform won't change while your program is running, consider using a Lazy to retrieve the platform once.

Don't like if-statements?

Let's first refactor the enum to match aforementioned conventions:

public enum OSPlatform
{
    NotSupported,
    Windows,
    OSX,
    Linux,
}

We could then use a Lazy:

 static readonly Lazy<OSPlatform> platform = new Lazy<OSPlatform>(GetPlatform, true);
 public static OSPlatform Platform => platform.Value;

And refactor the intitial method using a helper generator using a simple ValueTuple to avoid the boiler-plate if-statements.

private static IEnumerable
    <(OSPlatform Platform, RuntimeOSPlatform RuntimePlatform)?> EnumeratePlatforms() 
{
    yield return (OSPlatform.Windows, RuntimeOSPlatform.Windows);
    yield return (OSPlatform.OSX, RuntimeOSPlatform.OSX);
    yield return (OSPlatform.Linux, RuntimeOSPlatform.Linux);
}

private static OSPlatform GetPlatform()
{
    return EnumeratePlatforms().FirstOrDefault(p 
       => RuntimeInformation.IsOSPlatform(p.Value.RuntimePlatform))?.Platform ?? default;
}

I've created an alias to avoid redundant namespace code:

using RuntimeOSPlatform = System.Runtime.InteropServices.OSPlatform;

If you want to have some fun, you could refactor this solution to use Expression and some reflection to avoid creating hard-coded tuples.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You're writing answers at a gruelling pace :-O I cannot keep up reading them so there's a small voting lag lol \$\endgroup\$ – t3chb0t Aug 29 '19 at 17:16
  • \$\begingroup\$ @t3chb0t Yeah I checked you weren't only for 27 minutes o_O Please keep up :/ lol :p \$\endgroup\$ – dfhwze Aug 29 '19 at 17:18
  • 1
    \$\begingroup\$ I'll try but my tokenizer is driving me crazy :P I have more ideas so I'll post a new question soon; I'm adding a context to it and... no more spoilers ;-] \$\endgroup\$ – t3chb0t Aug 29 '19 at 17:20
  • \$\begingroup\$ I see you have enough green internet points for today... let's save some for tomorrow. \$\endgroup\$ – t3chb0t Aug 29 '19 at 18:15
  • 1
    \$\begingroup\$ This is a really nice answer, thank you :) \$\endgroup\$ – AndrewE Aug 29 '19 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.