Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an optional parameter be optionally required in C#?

Tags:

c#

Is there a possibility in C# to have an optional parameter be optionally required in specific situations and have it throw an error on compile time?

Let me explain with the code below as an example. The class ServiceResponse has a constructor accepting an enumeration value and an optional string. In case the enumeration value used to instantiate the class equals Error, the message becomes required. In the example code it will throw an ArgumentNullException when no message was supplied. Sadly this will only become visible on run time. However it should become visible on compile time so it warns the developer.

public class ServiceResponse
{
    public ServiceResponse(ServiceResult result, string message = null)
    {
        Result = result;
        Message = result == ServiceResult.Error ? message ?? throw new System.ArgumentNullException(nameof(message)) : message;
    }

    public string Message { get; }
    public ServiceResult Result { get; }
}

public enum ServiceResult {
    Ok,
    NotFound,
    Error
}
like image 789
Thrasher Avatar asked Oct 27 '25 13:10

Thrasher


2 Answers

I would make the constructor private and expose the 3 static methods required to instantiate.

You can also make the message field in CreateError(message) as NotNull, and some linters will pick this up and treat as a warning.

public class ServiceResponse
{
    // Change constructor to private
    private ServiceResponse(ServiceResult result, string message)
    {
        Result = result;
        Message = message;
    }

    public static ServiceResponse CreateOk(string message = null)
    {
        return new ServiceResponse(ServiceResult.OK, message);
    }

    public static ServiceResponse CreateNotFound(string message = null)
    {
        return new ServiceResponse(ServiceResult.NotFound, message);
    }

    public static ServiceResponse CreateError([NotNull] string message)
    {
        if (string.IsNullOrEmpty(message))
        {
            throw new ArgumentNullException(nameof(message));
        }

        return new ServiceResponse(ServiceResult.Error, message);
    }

    ... Other Class Properties
}
like image 151
James Woodall Avatar answered Oct 29 '25 04:10

James Woodall


Would static creation methods be an option?

public class ServiceResponse
{
    private ServiceResponse(ServiceResult result, string message = null)
    {
        Result = result;
        Message = message;
    }

    public string Message { get; }
    public ServiceResult Result { get; }

    public static ServiceResponse CreateInfo(ServiceResult result, string message = null)
    {
        return new ServiceResponse(result, message);
    }

    public static ServiceResponse CreateError(string message)
    {
        return new ServiceResponse(ServiceResult.Error, message);
    }
}

This doesn't prevent passing null to CreateError, but the developer probaly won't miss the message by accident.

like image 43
Jan Köhler Avatar answered Oct 29 '25 03:10

Jan Köhler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!