当用于返回值的对象为null时,您将从readonly属性抛出什么类型的异常
public class TestClass
{
SomeObject obj;
public string NameOfObject
{
get
{
if(obj == null)
{ // what exception type to throw here }
return obj.Name;
}
}
答案 0 :(得分:9)
我会抛出InvalidOperationException
。
ArgumentNullException
我只在方法参数为空时抛出。
如果methods参数处于无效状态,则抛出ArgumentException
。
答案 1 :(得分:7)
在这种情况下我会使用InvalidOperationException,因为对该属性的访问对于对象的当前状态无效。
根据MSDN文档:
“当方法调用对象的当前状态无效时抛出的异常。”
也:
“如果调用方法失败是由无效参数以外的原因引起的,则使用InvalidOperationException。”
在这种情况下,obj不是一个参数,这就是为什么我倾斜朝向“InvalidOperationException”
我不会在这里抛出NullReferenceException的原因:如果你没有添加任何特殊代码,那就是“。Net”会抛出的异常,那么为什么要添加冗余代码呢?
答案 2 :(得分:4)
您不应该抛出NullReferenceException。它适用于取消引用null对象的情况。在这种情况下,如果您要抛出NullReference,那么您可以将null检出并让框架在您尝试访问obj的名称时为其抛出。
答案 3 :(得分:3)
每个人都已经覆盖了明显的,所以这是另一种选择。
如果必须以某种方式初始化您的课程(必须在某个时候设置SomeObject
),请考虑实施ISupportInitialize。这表示您的班级用户在EndInit()
被调用之前未处于有效状态。不幸的是,没有预先存在的通用NotInitializedException
你可以使用(有一些但是特定于某些命名空间),所以我建议将你的接口实现与这种异常的创建配对。
用户必须先调用BeginInit()
,然后配置实例,然后调用EndInit()
。在调用EndInit()
时,请检查您的实例的状态。如果未正确初始化,则可以抛出InvalidOperationException。如果用户在初始化之前尝试使用您的实例,则会抛出NotInitializedException。
它的工作量更多,但优势在于您为用户创造了更广泛的“成功之处”,确保他们通过快速和早期失败以及您的类型的定义(正确)来正确使用您的类界面非常清楚你期望的)。它还可以为您提供更多的“空间”,用于记录您的课程应该如何使用。
答案 4 :(得分:2)
除非你在某个地方说这个属性永远不会为null,你为什么要抛出异常呢?
话虽如此,如果你保证,我会抛出InvalidOperationException
。
InvalidOperationException
是
a时抛出的异常 方法调用无效 对象的当前状态。
答案 5 :(得分:1)
我会抛出InvalidOperationException
,但前提是:
- obj
null
是合法的,用户有责任检查此事,或者
- obj
首先null
是不合法的(即obj != null
是一个类不变量)
如果上述情况都不属于这种情况(即,obj
为null
是合法的,并且在使用该属性之前未明确要求用户代码检查此内容),则我根本不会扔,而是返回null
。
答案 6 :(得分:1)
我会重新审视设计,以便首先不存在这种状态,即obj为空。通常从API的角度来看,您应该能够善意地调用getter,它会因为对象处于未知状态而不会爆炸。
例如,为什么不将'SomeObject obj'作为构造函数参数并在构造点使用参数验证。这将确保'obj'的状态始终正确,即构造后非空。
有许多模式可用于确保对象在用户可用时具有正确的状态。
答案 7 :(得分:1)
查看您提供的代码,而不了解您的设计假设,我会说您根本不应该测试obj == null
并让框架抛出NullReferenceException
。那你为什么要这个测试呢?我能想到的一个原因是你希望有一个更有意义的错误信息用于调试,但是你应该使用Debug.Assert(obj != null, "Your message here")
。