[英]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. 在C#中,我想与调用方法进行通信,传递给对象的参数导致其实例化失败。
// 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. 请注意,.NET框架中的行为类似于“Banana”示例(其中只有某些值适合实例化对象)不使用构造函数,而是使用静态工厂方法。 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.
例如, System.Net.WebRequest没有公共构造函数,而是使用静态Create方法,如果提供的字符串不是有效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: 因此,对于您的代码,我会将Banana的构造函数更改为protected,并引入如下方法:
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.
事实上,如果您将无效的文件名传递给其构造函数,System.IO.FileStream就是这样做的。 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").
我想使用静态工厂方法的想法只是更明确地说明如何创建实例(例如,如果上面的方法被称为“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.
为了证明这一点,打开反射器并查看BCL中的大多数类以及它们可以在构造上抛出的异常。
As an example. 举个例子。 List(IEnumerable collection) will throw an exception if collection is null.
如果collection为null,List(IEnumerable collection)将抛出异常。 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.
通过defenition,构造函数不返回值,因此您不能返回错误代码。
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 ......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.