簡體   English   中英

在C#中構造函數失敗的最佳通信方式是什么?

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

在C#中,我想與調用方法進行通信,傳遞給對象的參數導致其實例化失敗。

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

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

拋出異常? 如果是這樣的話?

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

很多(所有?)的答案都說要拋出異常,但我確信我已經看到框架設計團隊的官方聲明建議不要拋棄構造函數中的異常。

請注意,.NET框架中的行為類似於“Banana”示例(其中只有某些值適合實例化對象)不使用構造函數,而是使用靜態工廠方法。 例如, System.Net.WebRequest沒有公共構造函數,而是使用靜態Create方法,如果提供的字符串不是有效URI,則可以引發異常。 除了一些例外 - 請參閱下面的更新。

因此,對於您的代碼,我會將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);
}

更新

好吧,從構造函數中拋出異常似乎並不是一個主意。 事實上,如果您將無效的文件名傳遞給其構造函數,System.IO.FileStream就是這樣做的。 我想使用靜態工廠方法的想法只是更明確地說明如何創建實例(例如,如果上面的方法被稱為“FromColor”)。

最常見的解決方案是拋出異常。 為了證明這一點,打開反射器並查看BCL中的大多數類以及它們可以在構造上拋出的異常。

舉個例子。 如果collection為null,List(IEnumerable collection)將拋出異常。 向調用者傳達錯誤的完美有效方式。

如果構造函數失敗,則應拋出異常。 通過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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM