Jon*_*eet 100 c# generics exception
我目前正在为UnconstrainedMelody编写一些代码,它具有与枚举有关的通用方法.
现在,我有一个带有一堆方法的静态类,这些方法只能用于"flags"枚举.我不能将其添加为约束...所以它们也可能会被其他枚举类型调用.在那种情况下,我想抛出异常,但我不确定要抛出哪一个.
只是为了使这个具体,如果我有这样的事情:
// 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
}
Run Code Online (Sandbox Code Playgroud)
投掷的最佳例外是什么?ArgumentException
听起来合乎逻辑,但它是一个类型参数,而不是一个普通的参数,这很容易混淆事物.我应该介绍自己的TypeArgumentException
课吗?用InvalidOperationException
吗?NotSupportedException
?还要别的吗?
我宁愿不为此创建我自己的例外,除非它显然是正确的事情.
Jef*_*nal 43
NotSupportedException
听起来很明显,但文档明确指出它应该用于不同的目的.从MSDN类备注:
基类中不支持某些方法,期望这些方法将在派生类中实现.派生类可能只实现基类中的方法的子集,并为不支持的方法抛出NotSupportedException.
当然,有一种方法NotSupportedException
显然足够好,特别是考虑到它的常识意义.话虽如此,我不确定它是否恰到好处.
鉴于无约束旋律的目的......
使用泛型方法/类可以完成各种有用的事情,其中存在"T:enum"或"T:delegate"的类型约束 - 但不幸的是,这些在C#中是禁止的.
这个实用程序库使用ildasm/ilasm解决禁止问题...
...... Exception
尽管我们必须在创建自定义之前必须满足高举证据,但似乎新的可能是有序的Exceptions
.类似的东西InvalidTypeParameterException
可能在整个库中有用(或者可能不是 - 这肯定是一个边缘情况,对吧?).
客户是否需要能够将其与BCL例外区分开来?什么时候客户不小心使用香草调用它enum
?您如何回答接受的答案所提出的问题?在编写自定义异常类时应考虑哪些因素?
Jar*_*Par 23
我会避免使用NotSupportedException.此异常用于未实现方法的框架中,并且存在指示不支持此类操作的属性.它不适合这里
我认为InvalidOperationException是你可以抛出的最合适的异常.
Rem*_*anu 13
对于无效的类型参数,通用编程不应在运行时抛出.它不应该编译,你应该有一个编译时执行.我不知道IsFlag<T>()
包含什么,但也许您可以将其转换为编译时执行,例如尝试创建只能使用'flags'创建的类型.也许一traits
堂课可以提供帮助.
更新
如果你必须抛出,我会投票给InvalidOperationException.原因是泛型类型具有参数,并且与(方法)参数相关的错误以ArgumentException层次结构为中心.但是,对ArgumentException 的建议说明了这一点
如果失败不涉及参数本身,则应使用InvalidOperationException.
在那里至少有一个信念的飞跃,方法参数建议也应用于通用参数,但SystemException hierachy imho中没有更好的东西.
我会使用NotSupportedException,因为这就是你所说的.不支持除特定枚举之外的其他枚举.当然,这将在异常消息中更清楚地说明.
我会去的NotSupportedException
.虽然ArgumentException
看起来很好,但是当传递给方法的参数是不可接受的时,它确实是预期的.类型参数是您要调用的实际方法的定义特征,而不是真正的"参数".InvalidOperationException
当你正在执行的操作在某些情况下有效时应抛出,但对于特定情况,这是不可接受的.
NotSupportedException
当操作本身不受支持时抛出.例如,在实现某个特定成员对某个类没有意义的接口时.这看起来像是类似的情况.
显然,Microsoft使用ArgumentException
了此方法,如“ 例外”部分中的Expression.Lambda <>,Enum.TryParse <>或Marshal.GetDelegateForFunctionPointer <>的示例所示。我也找不到任何指示相反的示例(尽管在本地参考源中搜索TDelegate
和TEnum
)。
因此,我认为可以安全地假设至少在Microsoft代码中,ArgumentException
除了基本变量之外,对无效的泛型类型参数使用通用的做法。鉴于docs中的异常描述不会区分这些异常,因此也没有太大的困难。
希望它能一劳永逸地决定问题。