13.4 User-defined conversions

本文围绕C#中用户自定义类型转换展开。介绍了允许声明的用户自定义转换的条件,阐述了其评估过程,包括寻找适用操作符、确定最具体源类型和目标类型等步骤。还分别说明了用户自定义隐式和显式转换的处理流程及可能出现的编译错误情况。
C# allows the pre-defined implicit and explicit conversions to be augmented
by user-defined conversions.
User-defined conversions are introduced by declaring conversion operators (?
7.9.3) in class and struct
types.
13.4.1 Permitted user-defined conversions
C# permits only certain user-defined conversions to be declared. In
particular, it is not possible to redefine
an already existing implicit or explicit conversion. A class or struct is
permitted to declare a conversion from
a source type S to a target type T only if all of the following are true:
?S and T are different types.
?Either S or T is the class or struct type in which the operator
declaration takes place.
?Neither S nor T is object or an interface-type.
?T is not a base class of S, and S is not a base class of T.
The restrictions that apply to user-defined conversions are discussed
further in ?7.9.3.
13.4.2 Evaluation of user-defined conversions
A user-defined conversion converts a value from its type, called the source
type, to another type, called the
target type. Evaluation of a user-defined conversion centers on finding the
most specific user-defined
conversion operator for the particular source and target types. This
determination is broken into several
steps:
?Finding the set of classes and structs from which user-defined conversion
operators will be considered.
This set consists of the source type and its base classes and the target
type and its base classes (with the
implicit assumptions that only classes and structs can declare user-defined
operators, and that non-class
types have no base classes).
?From that set of types, determining which user-defined conversion
operators are applicable. For a
conversion operator to be applicable, it must be possible to perform a
standard conversion (?3.3) from
the source type to the operand type of the operator, and it must be
possible to perform a standard
conversion from the result type of the operator to the target type.
?From the set of applicable user-defined operators, determining which
operator is unambiguously the
most specific. In general terms, the most specific operator is the operator
whose operand type is
?closest? to the source type and whose result type is ?closest? to the
target type. The exact rules for
establishing the most specific user-defined conversion operator are defined
in the following sections.
Once a most specific user-defined conversion operator has been identified,
the actual execution of the userdefined
conversion involves up to three steps:
?First, if required, performing a standard conversion from the source type
to the operand type of the userdefined
conversion operator.
?Next, invoking the user-defined conversion operator to perform the
conversion.
?Finally, if required, performing a standard conversion from the result
type of the user-defined
conversion operator to the target type.
Evaluation of a user-defined conversion never involves more than one
user-defined conversion operator. In
other words, a conversion from type S to type T will never first execute a
user-defined conversion from S to
X and then execute a user-defined conversion from X to T.
Exact definitions of evaluation of user-defined implicit or explicit
conversions are given in the following
sections. The definitions make use of the following terms:
?If a standard implicit conversion (?3.3.1) exists from a type A to a
type B, and if neither A nor B are
interface-types, then A is said to be encompassed by B, and B is said to
encompass A.
?The most encompassing type in a set of types is the one type that
encompasses all other types in the set.
If no single type encompasses all other types, then the set has no most
encompassing type. In more
intuitive terms, the most encompassing type is the ?largest? type in the
set?the one type to which each
of the other types can be implicitly converted.
?The most encompassed type in a set of types is the one type that is
encompassed by all other types in the
set. If no single type is encompassed by all other types, then the set has


no most encompassed type. In
more intuitive terms, the most encompassed type is the ?smallest? type in
the set?the one type that can
be implicitly converted to each of the other types.
13.4.3 User-defined implicit conversions
A user-defined implicit conversion from type S to type T is processed as
follows:
?Find the set of types, D, from which user-defined conversion operators
will be considered. This set
consists of S (if S is a class or struct), the base classes of S (if S is a
class), T (if T is a class or struct),
and the base classes of T (if T is a class).
?Find the set of applicable user-defined conversion operators, U. This set
consists of the user-defined
implicit conversion operators declared by the classes or structs in D that
convert from a type
encompassing S to a type encompassed by T. If U is empty, the conversion is
undefined and a compiletime
error occurs.
?Find the most specific source type, SX, of the operators in U:
If any of the operators in U convert from S, then SX is S.
Otherwise, SX is the most encompassed type in the combined set of source
types of the operators in U. If no
most encompassed type can be found, then the conversion is ambiguous and a
compile-time error occurs.
?Find the most specific target type, TX, of the operators in U:
If any of the operators in U convert to T, then TX is T.
Otherwise, TX is the most encompassing type in the combined set of target
types of the operators in U. If no
most encompassing type can be found, then the conversion is ambiguous and a
compile-time error occurs.
?If U contains exactly one user-defined conversion operator that converts
from SX to TX, then this is the
most specific conversion operator. If no such operator exists, or if more
than one such operator exists,
then the conversion is ambiguous and a compile-time error occurs.
Otherwise, the user-defined
conversion is applied:
If S is not SX, then a standard implicit conversion from S to SX is
performed.
The most specific user-defined conversion operator is invoked to convert
from SX to TX.
If TX is not T, then a standard implicit conversion from TX to T is
performed.
13.4.4 User-defined explicit conversions
A user-defined explicit conversion from type S to type T is processed as
follows:
?Find the set of types, D, from which user-defined conversion operators
will be considered. This set
consists of S (if S is a class or struct), the base classes of S (if S is a
class), T (if T is a class or struct),
and the base classes of T (if T is a class).
?Find the set of applicable user-defined conversion operators, U. This set
consists of the user-defined
implicit or explicit conversion operators declared by the classes or
structs in D that convert from a type
encompassing or encompassed by S to a type encompassing or encompassed by
T. If U is empty, the
conversion is undefined and a compile-time error occurs.
?Find the most specific source type, SX, of the operators in U:
If any of the operators in U convert from S, then SX is S.
Otherwise, if any of the operators in U convert from types that encompass
S, then SX is the most
encompassed type in the combined set of source types of those operators. If
no most encompassed type can
be found, then the conversion is ambiguous and a compile-time error occurs.
Otherwise, SX is the most encompassing type in the combined set of source
types of the operators in U. If no
most encompassing type can be found, then the conversion is ambiguous and a
compile-time error occurs.
?Find the most specific target type, TX, of the operators in U:
If any of the operators in U convert to T, then TX is T.
Otherwise, if any of the operators in U convert to types that are
encompassed by T, then TX is the most
encompassing type in the combined set of target types of those operators.
If no most encompassing type can
be found, then the conversion is ambiguous and a compile-time error occurs.
Otherwise, TX is the most encompassed type in the combined set of target
types of the operators in U. If no
most encompassed type can be found, then the conversion is ambiguous and a
compile-time error occurs.
?If U contains exactly one user-defined conversion operator that converts
from SX to TX, then this is the
most specific conversion operator. If no such operator exists, or if more
than one such operator exists,
then the conversion is ambiguous and a compile-time error occurs.
Otherwise, the user-defined
conversion is applied:
If S is not SX, then a standard explicit conversion from S to SX is
performed.
The most specific user-defined conversion operator is invoked to convert
from SX to TX.
If TX is not T, then a standard explicit conversion from TX to T is
performed.
在 Oracle PL/SQL 中,用户可以通过定义自定义异常(User-Defined Exception)来处理特定业务逻辑中的错误情况。与预定义异常不同,用户自定义异常需要显式地声明、抛出和捕获,以确保程序在出现异常时能够按照预期流程进行处理。 ### 声明用户自定义异常 用户自定义异常在 PL/SQL 块的声明部分通过 `EXCEPTION` 关键字定义。定义的异常变量可以与特定的错误代码绑定,以便在抛出异常时使用。例如: ```sql DECLARE exception_test EXCEPTION; ``` 该语句定义了一个名为 `exception_test` 的异常变量,用于在程序中捕获和处理特定异常情况[^3]。 ### 绑定异常代码 通过 `PRAGMA EXCEPTION_INIT` 可以将自定义异常与特定的错误代码绑定。绑定的错误代码范围必须满足以下条件: - 不能为 `-1403` 或 `0`、`100` - 不能小于 `-1000000` 例如,将异常变量 `exception_test` 绑定到错误代码 `-20998`: ```sql PRAGMA EXCEPTION_INIT(exception_test, -20998); ``` 此绑定允许在程序中捕获特定错误代码的异常,并进行相应的处理。 ### 抛出自定义异常 用户可以通过 `RAISE` 语句显式地抛出自定义异常。例如: ```sql BEGIN RAISE exception_test; ``` 该语句触发 `exception_test` 异常,并将控制权转移到异常处理部分。此外,也可以使用 `RAISE_APPLICATION_ERROR` 函数抛出带有自定义描述的异常。例如: ```sql RAISE_APPLICATION_ERROR(-20998, 'User defined exception'); ``` 该函数抛出的异常代码必须在 `-20999` 到 `-20000` 之间,并附带描述信息,以便在日志或调试过程中提供更清晰的错误信息[^3]。 ### 捕获和处理异常 在 PL/SQL 块中,异常处理部分以 `EXCEPTION` 关键字开头,包含一个或多个 `WHEN` 子句用于捕获异常。例如: ```sql EXCEPTION WHEN exception_test THEN DBMS_OUTPUT.PUT_LINE('Caught user-defined exception: ' || SQLERRM); ``` 该语句捕获 `exception_test` 异常,并输出错误信息。若需要处理多个异常,可以在 `WHEN` 子句中使用 `OR` 连接多个异常名称,或者使用 `WHEN OTHERS THEN` 捕获所有未明确处理的异常[^2]。 ### 示例代码 以下是一个完整的示例,展示如何声明、绑定、抛出和捕获用户自定义异常: ```sql DECLARE exception_test EXCEPTION; PRAGMA EXCEPTION_INIT(exception_test, -20998); BEGIN RAISE_APPLICATION_ERROR(-20998, 'User defined exception'); EXCEPTION WHEN exception_test THEN DBMS_OUTPUT.PUT_LINE('Caught user-defined exception: ' || SQLERRM); END; ``` 执行结果: ``` Caught user-defined exception: ORA-20998: user defined exception PL/SQL procedure successfully completed. ``` 该示例展示了用户自定义异常的完整生命周期,包括声明、绑定、抛出和捕获过程。通过这种方式,可以实现对业务逻辑中特定异常情况的精细控制和响应。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值