Generic C++ Properties
Generics are parameterized types supported by the common language runtime. A parameterized type is a type that is defined with an unknown type parameter that is specified when the generic is used.
C++ supports templates and both templates and generics support parameterized types to create typed collection classes. However, templates provide compile-time parameterization. You cannot reference an assembly containing a template definition and create new specializations of the template.
Once compiled, a specialized template looks like any other class or method. In contrast, generics are emitted in MSIL as a parameterized type known by the runtime to be a parameterized type; source code that references an assembly containing a generic type can create specializations of the generic type.
Class types, as long as they are managed types, may be generic. The type of object in the list would be the type parameter. If you needed a List class for many different types of objects, before generics you might have used a List that takes System::Object as the item type.
But that would allow any object to be used in the list. Such a list would be called an untyped collection class. You could check the type at runtime and throw an exception. Or, you might have used a template, which would lose its generic quality once compiled into an assembly. Consumers of your assembly could not create their own specializations of the template. Generics allow you to create typed collection classes, say List<int> and List<double> ("List of double") which would generate a compile-time error if you tried to put a type that the collection was not designed to accept into the typed collection.
A generic declaration contains one or more unknown types known as type parameters. Type parameters are given a name which stands for the type within the body of the generic declaration. The type parameter is used as a type within the body of the generic declaration. The generic declaration for List<T> contains the type parameter T.
The type argument is the actual type used in place of the type parameter when the generic is specialized for a specific type or types. For example, int is the type argument in List<int>. Value types and handle types are the only types allowed in as a generic type argument.
A type constructed from a generic type is referred to as a constructed type. A type not fully specified, such as List<T> is an open constructed type; a type fully specified, such as List<double>, is a closed constructed type or specialized type. Open constructed types may be used in the definition of other generic types or methods and may not be fully specified until the enclosing generic is itself specified.
Handles types and value types may be used as type arguments. In the generic definition, in which either type may be used, the syntax is that of reference types.
For example, the -> operator is used to access members of the type of the type parameter whether or not the type eventually used is a reference type or a value type. When a value type is used as the type argument, the runtime generates code that uses the value types directly without boxing the value types.
Type parameters in a generic class are treated like other identifiers. However, because the type is not known, there are restrictions on their use. For example, you cannot use members and methods of the type parameter class unless the type parameter is known to support these members. That is, in order access a member through the type parameter, you must add the type that contains the member to the type parameter's constraint list.
A default instance of the type parameter may be created by using the () operator.
T t = T();
where T is a type parameter in a generic class or method definition, initializes the variable to its default value. If T is a ref class it will be a null pointer; if T is a value class, the object is initialized to zero. This is called a default initializer.
Generic functions may be necessary if the function's parameters are of an unknown type, or if the function itself must work with generic types. In many cases where System::Object may have been used in the past as a parameter for an unknown object type, a generic type parameter may be used instead, allowing for more type-safe code. Any attempt to pass in a type that the function was not designed for would be flagged as an error at compile time. Using System::Object as a function parameter, the inadvertent passing of an object that the function wasn't intended to deal with would not be detected, and you would have to cast the unknown object type to a specific type in the function body, and account for the possibility of an InvalidCastException. With a generic, code attempting to pass an object to the function would cause a type conflict so the function body is guaranteed to have the correct type.
A generic function is a function that is declared with type parameters.
When called, actual types are used instead of the type parameters.
Additional declarative information.modifiers (Optional)
A modifier for the function, such as static. virtual is not allowed since virtual methods may not be generic.return-type
The type returned by the method. If the return type is void, no return value is required.identifier
The function name.type-parameter identifier(s)
Comma-separated identifiers list.formal-parameters (Optional)
This specifies restrictions on the types that may be used as type arguments, and takes the form specified in Constraints.function-body
The body of the method, which may refer to the type parameter identifiers.Generic functions are functions declared with a generic type parameter. They may be methods in a class or struct, or standalone functions. A single generic declaration implicitly declares a family of functions that differ only in the substitution of a different actual type for the generic type parameter.
When called, the generic type parameter is replaced by an actual type. The actual type may be explicitly specified in angled brackets using syntax similar to a template function call. If called without the type parameters, the compiler will attempt to deduce the actual type from the parameters supplied in the function call. If the intended type argument cannot be deduced from the parameters used, the compiler will report an error.
For example, the following functions can be overloaded:
Collection classes in the past would use System::Object to store elements in a collection. Insertion of objects of a type that the collection was not designed for was not flagged at compile time, and often not even when the objects were inserted. Usually, an object would be cast to some other type when it was accessed in the collection. Only when the cast failed would the unexpected type be detected. Generics solves this problem at compile time by detecting any code that inserts a type that doesn't match (or implicitly convert to) the type parameter of the generic collection
A generic class is declared using the following form:
Additional declarative information.class-key
Either class or typenametype-parameter-identifier(s)
Comma-separated list of identifiers specifying the names of the type parameters.constraint-clauses
A list (not comma-separated) of where clauses specifying the constraints for the type parameters. Takes the form: where type-parameter-identifier : constraint-list ...constraint-list
Allowed accessibility modifiers include public and private.identifier
The name of the generic class, any valid C++ identifier.modifiers (optional)
Allowed modifiers include sealed and abstract.base-list
A list that contains the one base class and any implemented interfaces, all separated by commas.class-body
The body of the class, containing fields, member functions, etc.declarators
Declarations of any variables of this type. For example: ^identifier[, ...]
C++ supports templates and both templates and generics support parameterized types to create typed collection classes. However, templates provide compile-time parameterization. You cannot reference an assembly containing a template definition and create new specializations of the template. Once compiled, a specialized template looks like any other class or method. In contrast, generics are emitted in MSIL as a parameterized type known by the runtime to be a parameterized type; source code that references an assembly containing a generic type can create specializations of the generic type.
Re: Generic C++ Properties
ok got it
|All times are GMT +5.5. The time now is 02:51.|