Читайте также: |
|
The purpose of dynamic binding is to allow C# programs to interact with dynamic objects, i.e. objects that do not follow the normal rules of the C# type system. Dynamic objects may be objects from other programming languages with different types systems, or they may be objects that are programmatically setup to implement their own binding semantics for different operations.
The mechanism by which a dynamic object implements its own semantics is implementation defined. A given interface – again implementation defined – is implemented by dynamic objects to signal to the C# run-time that they have special semantics. Thus, whenever operations on a dynamic object are dynamically bound, their own binding semantics, rather than those of C# as specified in this document, take over.
While the purpose of dynamic binding is to allow interoperation with dynamic objects, C# allows dynamic binding on all objects, whether they are dynamic or not. This allows for a smoother integration of dynamic objects, as the results of operations on them may not themselves be dynamic objects, but are still of a type unknown to the programmer at compile-time. Also dynamic binding can help eliminate error-prone reflection-based code even when no objects involved are dynamic objects.
The following sections describe for each construct in the language exactly when dynamic binding is applied, what compile time checking – if any – is applied, and what the compile-time result and expression classification is.
7.2.3 Types of constituent expressions
When an operation is statically bound, the type of a constituent expression (e.g. a receiver, and argument, an index or an operand) is always considered to be the compile-time type of that expression.
When an operation is dynamically bound, the type of a constituent expression is determined in different ways depending on the compile-time type of the constituent expression:
· A constituent expression of compile-time type dynamic is considered to have the type of the actual value that the expression evaluates to at runtime
· A constituent expression whose compile-time type is a type parameter is considered to have the type which the type parameter is bound to at runtime
· Otherwise the constituent expression is considered to have its compile-time type.
Operators
Expressions are constructed from operands and operators. The operators of an expression indicate which operations to apply to the operands. Examples of operators include +, -, *, /, and new. Examples of operands include literals, fields, local variables, and expressions.
There are three kinds of operators:
· Unary operators. The unary operators take one operand and use either prefix notation (such as –x) or postfix notation (such as x++).
· Binary operators. The binary operators take two operands and all use infix notation (such as x + y).
· Ternary operator. Only one ternary operator,?:, exists; it takes three operands and uses infix notation (c? x: y).
The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators (§7.3.1).
Operands in an expression are evaluated from left to right. For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. This is separate from and unrelated to operator precedence.
Certain operators can be overloaded. Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type (§7.3.2).
Дата добавления: 2015-11-16; просмотров: 71 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Static and Dynamic Binding | | | Operator overloading |