对于无效genericstypes参数的最佳例外
我目前正在为UnconstrainedMelody编写一些代码,它具有通用方法来处理枚举。
现在,我有一个静态类与一堆方法, 只是用于“旗”枚举。 我不能添加这个作为约束…所以有可能他们也会被其他枚举types调用。 在这种情况下,我想抛出一个exception,但我不确定哪一个抛出。
只是为了使这个具体,如果我有这样的东西:
// Returns a value with all bits set by any values public static T GetBitMask<T>() where T : struct, IEnumConstraint { if (!IsFlags<T>()) // This method doesn't throw { throw new ??? } // Normal work here }
什么是最好的例外扔? ArgumentException
听起来合乎逻辑,但它是一个types参数而不是一个正常的参数,这很容易混淆。 我应该引入我自己的TypeArgumentException
类吗? 使用InvalidOperationException
? NotSupportedException
? 还要别的吗?
我宁愿不为此创造我自己的例外,除非这显然是正确的事情。
NotSupportedException
听起来很像它,但文档明确指出它应该用于不同的目的。 来自MSDN类的言论:
有基类中不支持的方法,期望这些方法将在派生类中实现。 派生类可能只实现基类的一部分方法,并为不支持的方法抛出NotSupportedException。
当然,有一种NotSupportedException
方式显然是很好的,特别是在常识的意义上。 话虽如此,我不确定是否正确。
鉴于无拘束旋律的目的…
有generics方法/类的types约束“T:enum”或“T:委托”可以做很多有用的事情 – 但不幸的是,这些在C#中是禁止的。
这个实用程序库工作在禁止使用ildasm / ilasm …
…尽pipe在创build自定义Exceptions
之前,我们必须满足很高的举证责任,但是看起来像一个新的Exception
可能是有序的。 类似InvalidTypeParameterException
东西在整个库中可能是有用的(或者不是 – 这肯定是一个边缘情况,对吗?)。
客户需要能够区分BCL例外吗? 什么时候客户不小心用香草enum
来调用这个? 你将如何回答接受的答案提出的问题在编写自定义exception类时应考虑哪些因素?
我会避免NotSupportedException。 这个exception在没有实现方法的框架中使用,并且有一个属性指示不支持这种types的操作。 这不适合在这里
- 无耻的自我参考: http : //blogs.msdn.com/jaredpar/archive/2008/12/12/notimplementedexception-vs-notsupportedexception.aspx
我认为InvalidOperationException是你可以抛出的最合适的exception。
generics编程不应该在运行时抛出无效的types参数。 它不应该编译,你应该有一个编译时间执行。 我不知道IsFlag<T>()
包含了什么,但也许你可以把它变成一个编译时执行,就像试图创build一个只能用'flags'创build的types一样。 也许traits
课可以帮助。
更新
如果你必须抛出,我会投票InvalidOperationException。 原因是genericstypes具有参数 ,与(方法)参数相关的错误以ArgumentException层次结构为中心。 但是,关于ArgumentException的build议表明
如果失败不涉及参数本身,则应使用InvalidOperationException。
在那里至less有一个信仰的飞跃, 方法参数的build议也适用于generics参数,但在SystemException hierachy imho没有什么更好的。
我会使用NotSupportedException,因为这是你所说的。 其他枚举比特定的不支持 。 这个例外情况当然会更清楚地说明。
我会去与NotSupportedException
。 虽然ArgumentException
看起来很好,但是当传递给一个方法的参数是不可接受的时候真的是这样的。 types参数是您要调用的实际方法的一个决定性特征,而不是真正的“参数”。 在某些情况下,您正在执行的操作可能是有效的,但在特定情况下,应该抛出InvalidOperationException
,这是不可接受的。
在操作本质上不受支持时抛出NotSupportedException
。 例如,在实现一个特定的成员对类没有意义的接口时。 这看起来像一个类似的情况。
Id与NotSupportedExpcetion一起去。
抛出一个自定义的exception应该始终在任何可疑的情况下完成。 无论API用户需要如何,自定义exception将始终有效。 如果开发者不关心,开发者可以捕获任何一种exceptiontypes,但是如果开发者需要特殊的处理,他将成为SOL。
显然,微软使用ArgumentException
为例,如exception部分中Expression.Lambda <> , Enum.TryParse <>或Marshal.GetDelegateForFunctionPointer <>的示例所示。 我找不到任何示例,否则(尽pipesearchTDelegate
和TEnum
本地参考源)。
所以,我认为可以肯定的是,至less在Microsoft代码中,除了基本variables之外,对于无效的genericstypes参数使用ArgumentException
是一种常见的做法。 鉴于文档中的例外描述不能区分这些内容,也不是太过分。
希望它能够一劳永逸地解决问题。
如何从NotSupportedExceptioninheritance。 虽然我同意@Mehrdad的说法是最有意义的,但是我听到你的观点,认为这看起来不太合适。 因此,从NotSupportedExceptioninheritance,这样编码对您的API的人仍然可以捕获NotSupportedException。
我总是小心编写自定义的exception,纯粹是因为它们并不总是被清楚地logging下来,如果没有正确命名,会造成混淆。
在这种情况下,我会抛出标志检查失败的ArgumentException。 这一切都是真正的偏好。 我所看到的一些编码标准甚至可以定义在这种情况下抛出哪些types的exception。
如果用户试图传入不是枚举的东西,那么我会抛出一个InvalidOperationExceptionexception。
编辑:
其他人提出了一个有趣的观点,认为这不被支持。 我唯一关心的是一个NotSupportedExceptionexception,一般来说,这些exception是在将“暗物质”引入系统时抛出的exception,或者换句话说,“这个方法必须在这个接口上进入系统,但是我们赢了直到2.4版才开启“
我也看到了NotSupportedExceptions作为一个许可例外抛出“你正在运行这个软件的免费版本,这个function是不支持的”。
编辑2:
另一个可能的:
System.ComponentModel.InvalidEnumArgumentException
使用枚举器的无效参数时抛出exception。
我也投票InvalidOperationException。 我做了一个基于框架devise指南第二版的 .NETexception抛出指南的(不完整的)stream程图。 一会儿回来,如果任何人有兴趣。