A
new pseudo-type dynamic is presented into the C# type system. It is considered as System.Object, but in addition, any member access (method call, field,
property, or indexer access, or a delegate invocation) or application of an
operator on a value of such type is allowed without any type checking, and its tenacity
is postponed until run-time. This is known as Duck typing
// Returns the value of Length property
or field of any object which supports the length
int GetLengthOf(dynamic obj)
{
return obj.Length;
}
Now,
consider followings
// a string has a Length property, So,
It’s a valid
// returns 34 including white spaces
GetLengthOf("This
time my Return is Huge! - DON");
// an array has a Length property, So,
It’s a valid
// returns 3, holding 3 items in an
array
GetLengthOf(new int[] { 1, 2, 3 });
// but not an integer - an exception
will be thrown here at run-time
// returns exception as 'int' does not
contain a definition for 'Length'
GetLengthOf(42);
Dynamic method calls are triggered
by a value of type "dynamic" as any implicit or explicit parameter
(and not just a receiver). For example:
void PrintThis(dynamic obj)
{
// which overload of
Write() to call is decided at run-time
Response.Write(obj);
}
PrintThis(3*6);
// ends up calling Write(int)
PrintThis("Don
retruns"); // ends up calling Write(string)
Dynamic lookup is achieved using
three distinct mechanisms: COM IDispatch for COM objects, IDynamicMetaObjectProvider DLR interface for objects implementing that interface, and reflection
for all other objects. Any C# class can therefore intercept dynamic calls on
its instances by implementing IDynamicMetaObjectProvider.
In case of dynamic method and
indexer calls, overload resolution happens at run-time according to the actual
types of the values passed as arguments, but otherwise according to the usual
C# overloading resolution rules. Furthermore, in cases where the receiver in a
dynamic call is not itself dynamic, run-time overload resolution will only reflect
the methods that are exposed on the declared compile-time type of the receiver.
. For example:
class BaseClass
{
void Don(double me);
}
class DerivedClass : BaseClass
{
void Don(int me);
}
dynamic me = 55;
BaseClass b = new
DerivedClass();
// picks BaseClass.Don(double) because
b is of type Base, and DerivedClass.Don(int) is not exposed
b.Don(me);
dynamic myself = b;
// picks DerivedClass.Don(int)
myself.Don(me);
Any value returned from a dynamic
member access is itself of type dynamic. Values of type dynamic are implicitly convertible both from and to any other type.
In the code sample above, this permits GetLengthOf
function to treat the value returned by a call to Length as an integer without any explicit cast. At run-time, the
actual value will be converted to the requested type.
No comments:
Post a Comment