代码之家  ›  专栏  ›  技术社区  ›  Seibar

应该从属性集中引发什么异常?

  •  1
  • Seibar  · 技术社区  · 16 年前

    在.NET中,如果有人将非法值传递给 set { } 财产的一部分?

    例子:

    public string Provider
    {
        get { return _provider; }
        set
        {
            if (String.IsNullOrEmpty(value)) throw new Exception("Provider cannot be null or empty."); //what type of exception should be thrown here instead?
            _provider = value;
        }
    }
    

    注:

    我在问这个问题,因为它适用于.net,但它也适用于许多其他语言。所以,如果你有一个很好的答案适用于.NET框架以外的东西,请张贴!

    4 回复  |  直到 13 年前
        1
  •  7
  •   ctacke    16 年前

    ArgumentException ,ArgumentOutOfRangeException、ArgumentNullException或类似的。

        2
  •  1
  •   Andrzej Doyle    16 年前

    一般来说,我不同意jon b关于何时抛出异常的说法——如果在调用set()时抛出异常,它将捕获设置无效值的上下文。另一方面,如果您只是将其设置为某个伪值并将异常抛出到其他位置,那么根据您所采用的方法,客户机将要么看到该伪值,而不指示这不是实际设置的值,要么将收到一个不向其提供任何异常的异常对无效状态负责或如何纠正的想法。

    现在,在某些情况下,这种技术可能是有意义的-如果由于某些不可避免的原因,属性是非常不稳定的,并且您已经决定暂时设置非法属性是可以的,但是(基于某些外部同步)客户端不允许检索属性直到它被认为是合法的,稳定的价值。这也不太好,但我相信在这种情况下你可能会无能为力。

    由于您询问了.NET以外的语言,在Java中,在一般情况下,我会使用一个ILLALKALGUMUTENT异常——如果参数为NULL,则可能是一个很好的旧的NulLoPoExtExchange。

        3
  •  1
  •   PMBottas    13 年前

    我同意安德烈的看法。应该在“set”中引发异常,因为不应该将属性设置为无效值,您需要“捕获设置无效值时的上下文”

    我使用一个ArgumentException类,因为“under the hood”a“set”是对自动创建的名为“classname”的方法的调用。set“propertyName”(值)

    例如

    class MyClass
    {
      string name;
    
      public string Name {
        get {
          return name;
        }
        set {
          if (value==null) {
            throw new ArgumentNullException("value", "The value of the property Name cannot be set to null.");
          }
          name = value;
        }
      }
    
    }
    

    这在内部创建了两个方法

    public string get_Name()
    

    public void set_Name(string value)
    

    如果显示堆栈跟踪,则将从此处引发异常。

    这就是为什么我总是在消息中包含类似“属性名的值…”这样属性的用户就可以看到异常被抛出的位置,因为类库的用户将看不到名为set_someproperty(sometype value)的方法。

    (此外,这是根据“net framework 4-异常、捕获和抛出标准异常类型的设计指南( Here ) 在页面的“ArgumentException、ArgumentNullException和ArgumentOutOfRangeException”部分,它声明“对属性设置器的隐式值参数的名称使用值”)

        4
  •  0
  •   Jon B    16 年前

    在那种情况下我不会破例。如果属性是字符串,则可以将其设置为“”或空。当我尝试使用该属性(如在connect()函数中)时,应该抛出异常,并显示一条消息,指出该函数因属性无效而失败。