Programming in C Generics CSE 494 R proposed

  • Slides: 30
Download presentation
Programming in C# Generics CSE 494 R (proposed course for 459 Programming in C#)

Programming in C# Generics CSE 494 R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

Motivation l See the Type Unification and the use of the Array. List set

Motivation l See the Type Unification and the use of the Array. List set of slides. l In summary, four main goals: 1. 2. 3. 4. l Increase type safety (statically) Eliminate type casts Eliminate box’ing and unbox’ing C++ has templates Syntax is similar to C++

Generic Syntax l Write l public class Stack<T> { … } Design Note is

Generic Syntax l Write l public class Stack<T> { … } Design Note is customary to use T for a generic single type. T is the Ittype variable For multiple types or in cases where the type is l Stack<int> = name newshould Stack<int>(); clear amy. Stack more specific be used. This is pre-fixed by a capital T. l Can l have several type parameters Dictionary<TKey, TValue> l Compiler l will now enforce type safety my. Stack. Push(4. 3) // Compiler error

Terminology l Why l We separate the behavior from the type allowing more generic

Terminology l Why l We separate the behavior from the type allowing more generic behavior descriptions. l Also l the name Generic? called Parametric Polymorphism We supply a type parameter and the same code or behavior applies to this type.

Generic Parameterization l Generics l can be used with: Types Struct l Interface l

Generic Parameterization l Generics l can be used with: Types Struct l Interface l Class l Delegate l l Methods

Using Generics - Types l Can be used to easily create non-generic derived types:

Using Generics - Types l Can be used to easily create non-generic derived types: public class Int. Stack : Stack<int> { }

Using Generics - Types l Can A better type name here be used in

Using Generics - Types l Can A better type name here be used in internal fields, properties would be TCustomer. Info and methods of a class: public struct Customer<T> { private static List<T> customer. List; private T customer. Info; public T Customer. Info { get; set; } public int Compare. Customers( T customer. Info ); }

Using Generics - Types l Using the type is like using any other non

Using Generics - Types l Using the type is like using any other non -generic type. l The type parameter only needs to be specified during instantiation. Customer<int> fred = new Customer<int>(); fred. Customer. Info = 4;

Verifying Generic Types l In C#, generic types can be compiled into a class

Verifying Generic Types l In C#, generic types can be compiled into a class library or dll and used by many applications. l Differs from C++ templates, which use the source code to create a new type at compile time. l Hence, when compiling a generic type, the compiler needs to ensure that the code will work for any type.

Generic Constraints l What if we want totype write What if my requires parameters

Generic Constraints l What if we want totype write What if my requires parameters on all of their public class Stack<T> constructors? public T Pop. Empty() { return new T(); } } l Why would the compiler produce an error for this?

Generic Constraints A new keyword, where provides constraints on a type parameter. l A

Generic Constraints A new keyword, where provides constraints on a type parameter. l A base class or interface can be used as a constraint. l For instance l public interface IDrawable { public void Draw(); } l Need a constraint that Again, thisour can type T implements the be enforced at IDrawable interface. public class Scene. Graph<T> where T : IDrawable { compile time public void Render() { … T node; … node. Draw(); } l } No need to cast l Compiler uses type information to decide

Generic Constraints l Can also specify a class constraint. l That is, require a

Generic Constraints l Can also specify a class constraint. l That is, require a reference type: public class Car. Factory<T> where T : class { private T current. Car = null; l Forbids Car. Factory<int> and other value types. l Useful since I can not set an int to null.

Generic Constraints l Alternatively, require a value (struct) type. public struct Nullable<T> where T

Generic Constraints l Alternatively, require a value (struct) type. public struct Nullable<T> where T : struct { private T value; l Fixes the new problem (but is limited): public class Stack<T> where T : struct { public T Pop. Empty() { return new T(); } }

Using a Default Value l You may need to initialize a variable What do

Using a Default Value l You may need to initialize a variable What do I public class Graph. Node<T> { do if T is private T node. Label; int? private void Clear. Label() { node. Label = null; } l Why doesn’t this work?

Using a Default Value l The default keyword public class Graph. Node<T> { private

Using a Default Value l The default keyword public class Graph. Node<T> { private T node. Label; private void Clear. Label() { node. Label = default(T); } l If T is a reference type default(T) will be null. l For value types all bits are set to zero.

Constructor Constraint l Special constraint using the new keyword: public class Stack<T> where T

Constructor Constraint l Special constraint using the new keyword: public class Stack<T> where T : new() { public T Pop. Empty() { return new T(); } l } Parameter-less constructor constraint l l l Type T must provide a public parameter-less constructor No support for other constructors or other method syntaxes. The new() constraint must be the last constraint.

Primary Constraints l. A generic type parameter, like a regular type, can have zero

Primary Constraints l. A generic type parameter, like a regular type, can have zero or one primary constraints, including: Derived from a non-sealed concrete or abstract base type l The class constraint l The struct constraint l

Secondary Constraints l. A generic type parameter, like a regular type, can have zero

Secondary Constraints l. A generic type parameter, like a regular type, can have zero or more interface constraints public class Graph. Node<T> { where T : ICloneable, IComparable … }

The where clause l. A type parameter can only have one where clause, so

The where clause l. A type parameter can only have one where clause, so all constraints must be specified within a single where clause. l Not allowed: public class Graph. Node<T> { where T : My. Node, ICloneable where T : IComparable, new() … }

Multiple Type Parameters l. A generic type can be parameterized with many type place-holders;

Multiple Type Parameters l. A generic type can be parameterized with many type place-holders; public interface IFunction<TDomain, TRange> { TRange Evaluate(TDomain sample); } l 2 D, 3 D, complex function support with mappings from one domain to another.

Dependent Constraints l Each type parameter can have its own set of constraints (and

Dependent Constraints l Each type parameter can have its own set of constraints (and own where class). l You can also have one type parameter be dependent on another. public class Sub. Set<U, V> where U : V public class Group<U, V> where V : IEnumerable<U> { … }

Compilation Errors l class A {. . . } l class B {. .

Compilation Errors l class A {. . . } l class B {. . . } l class Incompat<S, T> where S: A, T where T: B {. . . }

Compilation Errors l class Struct. With. Class<S, T, U> where S: struct, T where

Compilation Errors l class Struct. With. Class<S, T, U> where S: struct, T where T: U where U: A {. . . }

Compilation Errors interface I<T> { void F(); } class X<U, V>: I<U>, I<V> {

Compilation Errors interface I<T> { void F(); } class X<U, V>: I<U>, I<V> { void I<U>. F() {. . . } void I<V>. F() {. . . } }

Generic Methods l C# also allow you to parameterize a method with generic types:

Generic Methods l C# also allow you to parameterize a method with generic types: public static void Swap<T>( ref T a, ref T b ) { T temp = a; a = b; b = temp; }

Generic Methods l The method does not need to be static. public class Report<T>

Generic Methods l The method does not need to be static. public class Report<T> : where T IFormatter { } public class Insurance { public Report<T> Produce. Report<T>() where T : IFormatter { … } }

Type Covariance l We say a type Derived is Covariant to the type, Base,

Type Covariance l We say a type Derived is Covariant to the type, Base, if Derived can be cast to Base. l Generic types are not covariant. My. Class<Derived> md; l My. Class<Base> mb = md; l

Java Generics v. C# l Java made the decision to keep backward compatible bytecode.

Java Generics v. C# l Java made the decision to keep backward compatible bytecode. Hence old JVM’s can run the new Java with generics code. l Ruins run-time type reflection. l l C# l 2. 0 requires a new CLR. Generics are supported in the IL code.

C++ Templates v. C# l C++ has slightly more powerful parametric polymorphism in that

C++ Templates v. C# l C++ has slightly more powerful parametric polymorphism in that nontype parameters can also be used. l No run-time type support or reflection. l Run-time (generics) versus compile-time (templates) l Requires you to expose your source code to everyone.

Assignment l In addition to Reading Chapters 1 -3 of the textbook and going

Assignment l In addition to Reading Chapters 1 -3 of the textbook and going through these lectures, you should: Memorize the C# keywords a-I in the appendix of the book. l Think of how you would design a program or set of programs to display memorization questions or flashcards. l Read careful through the errata for book for Chapters 1 -4. l