简体   繁体   中英

What is the best way to communicate that your constructor has failed in C#?

In C# I want to communicate to the calling method that the parameters passed to an object have caused its instantiation to fail.

// okay
Banana banana1 = new Banana("green");

// fail
Banana banana2 = new Banana("red");

Throw an exception? If so how?

throw new ArgumentException("Reason", "param name");

A lot (all?) of the answers are saying to throw an exception, but I'm sure I've seen official statements from the framework design team advising against throwing exceptions from constructors.

Note that the classes in the .NET framework that behave similarly to your "Banana" example (where only certain values are appropriate to instantiate the object with) don't use constructors, but instead use static factory methods. For example, System.Net.WebRequest has no public constructor, and instead uses a static Create method which can raise an exception if the supplied string is not a valid URI. With some exceptions - see my update below.

So for your code I would change Banana's constructor to protected, and introduce a method like this:

public static Banana Create(string color) 
{
    if (color != "green" && color != "yellow")
    {
        throw new ArgumentException("Color must be 'green' or 'yellow'", 
            "color");
    }
    return new Banana(color);
}

Update

Ok, it seems like it's not a bad idea to throw exceptions from a constructor. In fact, System.IO.FileStream does just that if you pass an invalid filename to its constructor. I guess the idea of using a static factory method is just one way of being more explicit about how you're creating the instance (for example, if the method above were called "FromColor").

The most accepted solution is to throw an exception. To prove this, open reflector and have a look at most of the classes from the BCL and the exceptions that they can throw on construction.

As an example. List(IEnumerable collection) will throw an exception if collection is null. A perfectly valid way of communicating errors to the caller.

If your constructor fails, you should throw an exception. By defenition, Constructors do not return values, so you cant return, say, an error code.

public class Banana 
{
    public Banana(string color)
    {
        if ( color == "red" )
          throw new SomeException("intialization failed, red is an invalid color");

    }
}
//////////////////////////////////////////////////////////     
try
{
    Banana banana1 = new Banana("green");
    banana1.whatever();
}
catch( SomeException error )
{
    // do something
}
finally
{
    // always do  this stuff
}

我想你想要ArgumentException ......

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM