的方法来创建一个对象

的方法来创建一个对象

问题描述:

我有一个构造的方法来创建一个对象

public Track(string path) 
{ 
     if (!File.Exists(path)) 
      throw new FileNotFoundException("File not found", path); 
     if (!IsAudioFile(path)) 
      throw new Exception("Illegal Audio Format"); 

     _path = path; 
     _id = Guid.NewGuid(); 
     _rate = 0; 
     _length = GetTrackLength(path); 

     TagLib.File file = TagLib.File.Create(path); 
     if (!file.Tag.IsEmpty) 
     { 
      try 
      { 
       _artist = file.Tag.Artists[0]; 
      } 
      catch (Exception e) 
      { 
       _artist = ""; 
      } 
      _title = file.Tag.Title; 
      try 
      { 
       _genre = file.Tag.Genres[0].ToGenre(); 
      } 
      catch (Exception e) 
      { 
       _genre = Genre.NoGenre; 
      } 
     } 
     else 
     { 
      _artist = "Unknown"; 
      _title = "Unknown"; 
      _genre = Genre.NoGenre; 
     } 
} 

我应该抛出一个异常,或者我应该选择创建对象的另一种方式? 例如:

Track track = new Track(path);
track = Track.GetInstance();

我会做一些小的修改,如下所示,以避免不必要的异常处理,并且还会在参数检查中抛出一个更具体的异常。就投入构造函数而言,这很好,因为它实际上只是特殊类型的方法。

关于创建新的Track的反馈:你可以放置一个GetTrack()方法在某种经理(TagManager为例),如果你认为new'ing了Track对象是什么,你的API应该将处理的给对消费者负责。

public Track(string path) 
{ 
    if (!File.Exists(path)) 
     throw new FileNotFoundException("File not found", path); 
    if (!IsAudioFile(path)) 
     throw new InvalidOperationException("Illegal Audio Format"); 

    _path = path; 
    _id = Guid.NewGuid(); 
    _rate = 0; 
    _length = GetTrackLength(path); 

    TagLib.File file = TagLib.File.Create(path); 
    if (!file.Tag.IsEmpty) 
    { 
     _title = file.Tag.Title; 

     if (file.Tag.Artists != null && file.Tag.Artists.Count > 0) 
      _artist = file.Tag.Artists[0]; 
     else 
      _artist = ""; 


     if (file.Tag.Genres != null && file.Tag.Genres.Count > 0) 
      _genre = file.Tag.Genres[0].ToGenre(); 
     else 
      _genre = Genre.NoGenre; 
    } 
    else 
    { 
     _artist = "Unknown"; 
     _title = "Unknown"; 
     _genre = Genre.NoGenre; 
    } 
} 

你的代码是正确的,图案很好。

但是,you shouldn't throw the base Exception class
相反,您应该抛出一个ArgumentException,InvalidDataExceptionInvalidOperationException。您也可以shouldn't catch the base Exception class
取而代之,您应该捕获ToGenre方法可能抛出的任何异常。

+0

你认为我做的一切正确? – Sergey 2010-11-14 15:14:31

+0

更好使用ArgumentException,我认为 – 2010-11-14 15:15:02

+0

@Segey:差不多。 – SLaks 2010-11-14 15:15:46

有(通常)没有理由有静态方法返回实例除非你正在做一个单身模式或需要重新使用现有的对象,而不是创建新的实例。

在构造函数中抛出异常很好,而且通常是正确的做事方式。

+0

我认为构造函数中的异常不是一个好的决定 – Sergey 2010-11-14 15:17:12

+1

@Sergey:在构造函数中抛出异常没有任何问题。 http://msdn.microsoft.com/en-us/library/bb386039。aspx普通(非'静态')构造函数不在列表中。 – SLaks 2010-11-14 15:18:06

+1

过去有些语言在构造中抛出异常(有时)是不好的。 C#不是其中之一。 – Donnie 2010-11-14 15:24:37

代码很酷。

  1. 您在开始工作之前检查参数。
  2. 您的代码清晰易读
  3. 您处理没有提供信息时设置默认值的情况。

我所能建议的不是使用泛型异常,而是抛出并捕获更具体的上下文。随意使用ArgumentException。

而且,只是CheckStyle的:

是,如果你想在若{}块添加代码,使用大括号{}始终如果是一个好的做法,你可以忘记把括号。虽然这里没有必要。