字符串参数的ArgumentException或ArgumentNullException?

时间:2010-03-19 20:54:27

标签: c# exception

就最佳做法而言,哪个更好:

public void SomeMethod(string str) 
{
    if(string.IsNullOrEmpty(str))
    {
        throw new ArgumentException("str cannot be null or empty.");
    }

    // do other stuff
}

public void SomeMethod(string str) 
{
    if(str == null) 
    {
        throw new ArgumentNullException("str");
    }

    if(str == string.Empty)
    {
        throw new ArgumentException("str cannot be empty.");
    }

    // do other stuff
}

第二个版本看起来更精确,但也比第一个版本更麻烦。我通常选择#1,但我想我会检查是否有争论#2。

4 个答案:

答案 0 :(得分:33)

我会说第二种方式确实更精确 - 是的,它更麻烦,但你总是可以将它包装在一个方法中,以避免不得不一直这样做。它甚至可以是一种扩展方法:

str.ThrowIfNullOrEmpty("str");


public static void ThrowIfNullOrEmpty(this string value, string name)
{
    if (value == null)
    {
        throw new ArgumentNullException(name);
    }
    if (value == "")
    {
        throw new ArgumentException("Argument must not be the empty string.",
                                    name);
    }
}

另一种可能有用的形式是如果一切正常则返回原始字符串。你可以这样写:

public Person(string name)
{
    this.name = name.CheckNotEmpty();
}

另一个需要考虑的选择是使用Code Contracts作为抛出自己的异常的替代方法。

答案 1 :(得分:5)

我建议使用第一个。如果你的方法不期望null或空字符串,那么传递null或empty是无关紧要的 - 报告和错误很重要,这就是第一个变体所做的。

答案 2 :(得分:0)

另一种可能性是public class SongInfoModel { public String SongName, ArtistName, Genre, Album, SongUrl,data; public long duration; Uri albumIDArtwork; public Long albumID; public SongInfoModel(String songName, String artistName, String genre, String album, String songurl, long duration, String data, Uri albumIDArtwork, Long albumID) { SongName = songName; ArtistName = artistName; Genre = genre; Album = album; SongUrl = songurl; this.duration = duration; this.data = data; this.albumIDArtwork = albumIDArtwork; this.albumID = albumID; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Uri getAlbumIDArtwork() { return albumIDArtwork; } public Long getAlbumID() { return albumID; } public void setAlbumID(Long albumID) { this.albumID = albumID; } public void setAlbumIDArtwork(Uri albumID) { this.albumIDArtwork = albumID; } public String getSongName() { return SongName; } public void setSongName(String songName) { SongName = songName; } public String getArtistName() { return ArtistName; } public void setArtistName(String artistName) { ArtistName = artistName; } public String getGenre() { return Genre; } public void setGenre(String genre) { Genre = genre; } public String getAlbum() { return Album; } public void setAlbum(String album) { Album = album; } public String getSongUrl() { return SongUrl; } public void setSongUrl(String songUrl) { SongUrl = songUrl; } public long getDuration() { return duration; } public void setDuration(long duration) { this.duration = duration; } } 例外:

  

当参数的值超出被调用方法定义的允许值范围时抛出的异常。

答案 3 :(得分:0)

在空字符串上添加空引用可能会造成极大的混乱-字符串的默认值为null,这表示未初始化的字符串,而空字符串可能会构成其他问题。

我喜欢乔恩·斯凯特(Jon Skeet)的想法,但是我喜欢显式地使用throw,并且没有单独的功能。

相反,您可以抛出以下课程:

 public class ArgumentNullOrEmptyException : ArgumentNullException
{
    #region Properties And Fields

    private static string DefaultMessage => $"A value cannot be null or empty{Environment.NewLine}";

    #endregion

    #region Construction and Destruction

    public ArgumentNullOrEmptyException()
        : base(DefaultMessage)
    {
    }

    public ArgumentNullOrEmptyException(string paramName)
        : base(paramName, 
                  $"{DefaultMessage}" +
                  $"Parameter name: {paramName}")
    {
    }

    public ArgumentNullOrEmptyException(string message, Exception innerException)
        : base($"{DefaultMessage}{message}", innerException)
    {
    }

    public ArgumentNullOrEmptyException(string paramName, string message)
        : base(paramName, 
              $"{DefaultMessage}" +
              $"Parameter name: {paramName}{Environment.NewLine}" +
              $"{message}")
    {
    }

    #endregion

    public static void ThrowOnNullOrEmpty(string paramName, string paramValue)
    {
        if(string.IsNullOrEmpty(paramValue))
            throw new ArgumentNullOrEmptyException(paramName);
    }
    public static void ThrowOnNullOrEmpty(string paramValue)
    {
        if (string.IsNullOrEmpty(paramValue))
            throw new ArgumentNullOrEmptyException();
    }


    public static void ThrowOnNullOrEmpty(string paramName, object paramValue)
    {
        //ThrowOnNullOrEmpty another object that could be 'empty' 

        throw new NotImplementedException();
    }
}



        private static void AFunctionWithAstringParameter(string inputString)
    {
        if(string.IsNullOrEmpty(inputString)) throw new ArgumentNullOrEmptyException(nameof(inputString));

        //Or ..
        ArgumentNullOrEmptyException.ThrowOnNullOrEmpty(nameof(inputString), inputString);
    }

请注意,我的派生类型仅调用基本异常类,而不是覆盖message属性。这是因为Visual Studio调试器的“附加信息”列出了内部消息,而不是覆盖的类型。这意味着这是在调试时很好地显示消息的唯一方法。