質問

So far I've learned that (usually) when you assert, you should also throw. At first I wasn't sure it was right, it just made sense1, and then this answer verified.

The problem I have is that it causes repeated-code (at least via contracts). Here's an example of a name field that can't be null or white-space:

 public String Name
 {
     get { return _name; }
     set
     {
         Contract.Requires(String.IsNullOrWhiteSpace(value) == false, "Names cannot be null or whitespace.");
         if (String.IsNullOrWhiteSpace(value))
             throw new ArgumentException("Names cannot be null or whitespace.");

         _name = value;
     }
 }

Clearly both the condition, and the error message are repeated. How should I handle it? In one property it's manageable but in a class with multiple fields it's littering.

Additional Information

I thought of using Contract.Requires<TException> (which would assert in debug and throw in release), but the condition (which is the code) would be the message of the exception, which would most likely be displayed to the user (a user would probably like to know why his program crashed, and I wouldn't want to show the actual code). Here's an example:

static void MyFunction(Boolean youCanSeeMyCode = false)
{
    Contract.Requires<Exception>(youCanSeeMyCode, "(This is the exception's message)");
}

...

try
{
    MyFunction();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Error");
}

Error Message

Any suggestions? I'm at a loss.


1 It made sense because if you only use assert and you still have a bug somewhere that you're unaware of, the release build would carry on as if everything's okay and hell could break loose.

役に立ちましたか?

解決

The answer you've linked to is about Debug.Assert, which is turned off for release builds by default. I've never liked that idea - it's like saying that it's only worth wearing a seatbelt when you're learning to drive, but not when you're driving at speed.

I would encourage you to just use Contract.Requires (no separate explicit throw statement) and then make sure that you configure your project so that preconditions are still checked in release builds. Your concern about the message being displayed to the user isn't a concern which should be addressed here - it should be addressed in your general exception handling. If you don't want to show exception messages to the user, don't show them... but do log them. You really shouldn't try to make exceptions meaningful to end users... that's not their purpose.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top