Monday, July 21, 2014

CLR via C# - CHAPTER 5 Primitive, Reference, and Value Types

Primitive, Reference, and Value  Types
Programming Language Primitive Types
Any data types the compiler directly supports are called primitive types. Primitive types map directly to types existing in the Framework Class Library (FCL).
Reference Types and Value Types
The CLR supports two kinds of types: reference types and value types.Value type instances are usually allocated on a thread’s stack.
The .NET Framework SDK documentation clearly indicates which types are reference types and which are value types.When looking up a type in the documentation, any type called a class is a reference type. On the other hand, the documentation refers to each value type as a structure or an enumeration.

All of the structures are immediately derived from the System.ValueTypeabstract type. System.Value Typeis itself immediately derived from the System.Objecttype. By definition, all value types must be derived from System.ValueType. All enumerations are derived from the System.Enumabstract type, which is itself derived from System.ValueType.

Object Equality and Identity
When defining your own type, if you decide to override Equals, you must ensure that it adheres
to the four properties of equality:
■ Equalsmust be reflexive; that is, x.Equals(x)must return true.
■ Equalsmust be symmetric; that is, x.Equals(y)must return the same value as y.Equals(x).
■ Equalsmust be transitive; that is, if x.Equals(y)returns trueand y.Equals(z)returns true, then x.Equals(z)must also return true.
■ Equalsmust be consistent. Provided that there are no changes in the two values being compared, Equalsshould consistently return trueor false.

When overriding the Equalsmethod, there are a couple more things that you’ll probably want
to do:
■ Have the type implement the System.IEquatable<T>interface’s Equalsmethod  This generic interface allows you to define a type-safe Equalsmethod. Usually, you’ll implement the Equalsmethod that takes an Objectparameter to internally call the type-safe Equals method.
■ Overload the ==and !=operator methods  Usually, you’ll implement these operator methods to internally call the type-safe Equalsmethod.

Object Hash Codes
If you define a type and override the Equalsmethod, you should also override the GetHashCode method.
The reason a type that defines Equalsmust also define GetHashCodeis that the implementation of the System.Collections.Hashtabletype, the System.Collections.Generic.Dictionary type, and some other collections require that any two objects that are equal must have the same hash code value.

Basically, when you add a key/value pair to a collection, a hash code for the key object is obtained first. This hash code indicates which “bucket” the key/value pair should be stored in. When the collection needs to look up a key, it gets the hash code for the specified key object. This code identifies the “bucket” that is now searched sequentially, looking for a stored key object that is equal to the specified key object.

When selecting an algorithm for calculating hash codes for instances of your type, try to follow these guidelines:
■ Use an algorithm that gives a good random distribution for the best performance of the hash table.
■ Your algorithm can also call the base type’s GetHashCodemethod, including its return value. However, you don’t generally want to call Object’s or ValueType’s GetHashCodemethod, because the implementation in either method doesn’t lend itself to high-performance hashing algorithms.
■ Your algorithm should use at least one instance field.
■ Ideally, the fields you use in your algorithm should be immutable; that is, the fields should be initialized when the object is constructed, and they should never again change during the object’s lifetime.
■ Your algorithm should execute as quickly as possible.
■ Objects with the same value should return the same code. For example, two Stringobjects with the same text should return the same hash code value.

The dynamicPrimitive Type
payload code

When the type of a field, method parameter, or method return type is specified as dynamic, the compiler converts this type to the System.Objecttype and applies an instance of System.Run­time.CompilerServices.DynamicAttribute to the field, parameter, or return type in metadata. If a local variable is specified as dynamic, then the variable’s type will also be of type Object, but the DynamicAttributeis not applied to the local variable because its usage is self-contained within the method. Because dynamicis really the same as Object, you cannot write methods whose signature differs only by dynamicand Object.
It is also possible to use dynamicwhen specifying generic type arguments to a generic class (reference type), a structure (value type), an interface, a delegate, or a method. When you do this, the compiler converts dynamicto Objectand applies DynamicAttributeto the various pieces of metadata where it makes sense. Note that the generic code that you are using has already been compiled and will consider the type to be Object; no dynamic dispatch will be performed because the compiler did not produce any payload code in the generic code.
Any expression can implicitly be cast to dynamicbecause all expressions result in a type that is rived from Object Normally, the compiler does not allow you to write code that implicitly casts an expression from Objectto another type; you must use explicit cast syntax. However, the compiler does allow you to cast an expression from dynamicto another type by using implicit cast syntax.

























































No comments:

Post a Comment