开发者

C#: Should the default value of an enum be None or Unknown?

开发者 https://www.devze.com 2023-01-05 15:35 出处:网络
Say you have an enum that represents an error code. There will be several codes, each with their own underlying int value; however, the enum value that gets the default 0 value seems like it should be

Say you have an enum that represents an error code. There will be several codes, each with their own underlying int value; however, the enum value that gets the default 0 value seems like it should be carefully considered.

In the case of an error code enum, there are two special values that I can think of: None (for cases when there is no error) and Unknown (for cases when no existing error code is appropriate, or perhaps even when error state cannot be detected).

One of these values seems like it should get 0, where the other will probably get something else like -1. Is it more appropriate to set the None value to 0, or the Unknown value to 0?

public enum ErrorCode
{
    None = -1,
    Unknown = 0,
    InsufficientPermissions,
    ConnectivityError,
    ...
}

public enum ErrorCode
{
    Unknown = -1,
    None = 0,
    InsufficientPermissions,
    Connecti开发者_开发问答vityError,
    ...
}

My instinct tells me that the default should be Unknown, but I'm curious if anyone has done it differently.


Since you're tagging your question with best-practices: don't use error codes when you can use exceptions.


In my opinion both Unknown or None mean the same thing in the context of the ErrorCode enumeration. My reasoning is that if I'm checking an error code than it's because I already have an error.

I'm also of the opinion that an error code enumeration is only useful in a custom exception or as custom data of an existing exception type and in both scenarios you will always have an error.


Definitely not a good practice. But if there is no other way...then I would generally go by the second option:

public enum ErrorCode 
{ 
    Unknown = -1, 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 

0 goes well by the convention 'No Error' and -1 goes fine with the understanding that there is some error (which may be unknown).


I guess I'll disagree with everyone else on this.

There's nothing wrong with error codes when used in the sense of "what is the current state of this feature."

To make up an example: if you have an optional networked temp folder, that you want to access, and you want to display the results from the most recent time that you attempted to access it, you would save that in an error code. Perhaps on a status bar you want to show the current state to the user.

For me, I would use None as 0, as the default. I see no reason to make Unknown be negative. Unknown is a perfectly fine error state. You can just put it at the end of the list. In practice, I have done

public enum ErrorCode
{
    None = 0,
    InsufficientPermissions,
    ConnectivityError,
    ...
    Unknown,
}

And to answer your question, I say None must be the default. None means: no error exists that you are aware of. Unknown would mean to me: an error exists that is so obscure that you can't account for it in your code.


First of all, you shouldn't have a None error code. Instead, call it "Success".

Now think about how you are going to check the error code. Most people expect something like this:

if (errorCode != Success)

or they use the shorthand

if (errorCode != 0)

So there you have it. Your Success code is 0, you don't have a None code, and Unknown can be anything you want.


Why return an ErrorCode value at all when there is no error?

Doesn't make a whole lot of sense. Removing that would resolve your issue. You could just make 0 be for Unkown:

public enum ErrorCode
{
    Unkown = 0,
    InsufficientPermissions,
    ConnectivityError
}

UPDATE

Your comment is a little scary. You should never have a method that returns a type of ErrorCode. It's very poor practice. Since ErrorCodes should only be returned in Exceptional circumstances, it's a good idea to throw Exceptions.

If you want, you can have a field in your custom Exception that contains the ErrorCode value.


I would actually have to disagree with anyone that says you should only use exceptions. When using any kind of application that uses a database you may want to store statuses for the data in the system. Whether they are error codes or some kind of status they are best represented in the database as integers.

Using and handling exceptions is a very important skill and should be used, but I believe that having an error code along with those exceptions is generally a good idea. It doesn't take too many additional resources and lends itself to be used in a database connected application.

I would actually suggest that change "None" to "Success" as suggested, but that you make "Success" a value of 1, and have all other errors increment from there. The reason behind this is because as a standard in most database applications the status columns are not nullable, and are generally tracked as integers. This can lead to issues if you use a success status of 0 because by default non nullable integer columns will be set to 0 if a user doesn't explicitly insert something else. This would lead to a false status / error code and cause problems in the future of your application. Not only that integer variables are automatically initialized to 0 by default in C# causing it to be an automatic success, so are enumerations if you don't set the initial value, and that is not something you want.

Also from a coding standpoint a 1 can also mean true, and so it goes well with success. There are situations where this may not be the case though. In Unix based systems a return of 0 means success/ no errors, and in other languages like c++ a 0 return is standard from the main function also indicating a successful execution of the main function.


ErrorCodes bad. Exceptions good. But to answer the question as asked:

If your enum has an "Unknown" value, it should be the default.


Ditto to all of the "I wouldn't do it responses," but if you insist, here's my $0.02.

ErrorCodes.None makes no sense, since there's no error. ErrorCodes.Unknown is not helpful. Try returning a nullable error code:

public ErrorCode? DoFoo()

Now you can check for null

var error = DoFoo();
if (error != null)
    // react

Still bad, but at least it allows you to not return an error code if there's no error.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号