Generic

25

Transcript of Generic

Page 1: Generic
Page 2: Generic

Generics

• The term generics means parameterized types.• Parameterized types are important because they

enable you to create classes, structures, interfaces, methods, and delegates in which the type of data upon which they operate is specified as a parameter.

• ability to create generalized code by operating through references of type object.

Page 3: Generic

• Generics also streamline the process because it is no longer necessary to employ casts to translate between object and the type of data that is actually being operated upon.

• Thus, generics expand your ability to re-use code, and let you do so safely and easily.

Page 4: Generic

A Simple Generics Example• using System;• class Gen<T> {• T ob;• public Gen(T o) {• ob = o;• }• public T GetOb() {• return ob;• }• public void ShowType() {• Console.WriteLine("Type of T is " + typeof(T));• }• }• // Demonstrate the generic class.• class GenericsDemo {• static void Main() {

» // Create a Gen reference for int.

• Gen<int> iOb;» // Create a Gen<int> object and assign its reference to iOb.

• iOb = new Gen<int>(102);

Page 5: Generic

» // Show the type of data used by iOb.

• iOb.ShowType();» // Get the value in iOb.

• int v = iOb.GetOb();• Console.WriteLine("value: " + v);• Console.WriteLine();

» // Create a Gen object for strings.

• Gen<string> strOb = new Gen<string>("Generics add power.");

» // Show the type of data stored in strOb.

• strOb.ShowType();» // Get the value in strOb.

• string str = strOb.GetOb();• Console.WriteLine("value: " + str); }}

Page 6: Generic

Output

• Type of T is System.Int32

• value: 102

• Type of T is System.String

• value: Generics add power.

Page 7: Generic

Error

• iOb = new Gen<double>(118.12); // Error!

• iOb is of type Gen<int>, it can’t be used to refer to an object of Gen<double>. This type checking is one of the main benefits of generics because it ensures type safety.

Page 8: Generic

Generic Types Differ Based on Their Type Arguments

• iOb = strOb; // Wrong!

• both iOb and strOb are of type Gen<T>, they are references to different types because their type arguments differ.

Page 9: Generic

Why generic?

• The answer is that generics automatically ensure the type safety of all operations involving Gen. In the process, generics eliminate the need for you to use casts and type-check code by hand.

Page 10: Generic

Next…

Page 11: Generic

Attributes• C# allows you to add declarative information to a

program in the form of an attribute. • An attribute defines additional information (metadata)

that is associated with a class, structure, method, and so on.

• For example, you might define an attribute that determines the type of button that a class will display.

• Attributes are specified between square brackets, preceding the item to which they apply.

• An attribute is not a member of a class. Rather, an attribute specifies supplemental information that is attached to an item.

Page 12: Generic

Attribute

• An attribute is supported by a class that inherits System.Attribute. Thus, all attribute classes must be subclasses of Attribute.

• By convention, attribute classes often use the suffix Attribute. For example, ErrorAttribute would be a name for an attribute class that described an error.

• This built-in attribute specifies the types of items to which the attribute can be applied.

Page 13: Generic

Creating an Attribute [AttributeUsage(AttributeTargets.All)]public class RemarkAttribute : Attribute { string pri_remark; // underlies Remark property

public RemarkAttribute(string comment) {

pri_remark = comment; }

public string Remark {

get { return pri_remark; }

}

}

Page 14: Generic

• The name of this attribute is RemarkAttribute. Its declaration is preceded by the AttributeUsage attribute, which specifies that RemarkAttribute can be applied to all types of items. Using AttributeUsage, it is possible to narrow the list of items to which an attribute can be attached, and we will examine its capabilities later in this chapter.

• Next, RemarkAttribute is declared and it inherits Attribute. Inside RemarkAttribute there is one private field, pri_remark, which supports one public, read-only property: Remark.This property holds the description that will be associated with the attribute. (Remark could also have been declared as an auto-implemented property with a private set accessor, but a read-only property is used for the purposes of illustration.) There is one public constructor that takes a string argument and assigns it to Remark.

Page 15: Generic

Attaching an Attribute

• Once you have defined an attribute class, you can attach the attribute to an item. An attribute precedes the item to which it is attached and is specified by enclosing its constructor inside square brackets. For example, here is how RemarkAttribute can be associated with a class:

• [RemarkAttribute("This class uses an attribute.")]• class UseAttrib {• // ...• }• This constructs a RemarkAttribute that contains the

comment, “This class uses an attribute.” This attribute is then associated with UseAttrib.

Page 16: Generic

Built-in Attributes

• C# defines many built-in attributes, but three are especially important because they apply to a wide variety of situations: AttributeUsage, Conditional, and Obsolete.

Page 17: Generic

AttributeUsage

• As mentioned earlier, the AttributeUsage attribute specifies the types of items to which an attribute can be applied. AttributeUsage is another name for the System.AttributeUsageAttribute class. AttributeUsage has the following constructor:

• AttributeUsage(AttributeTargets validOn)

• Here, validOn specifies the item or items upon which the attribute can be used.

Page 18: Generic

• AttributeTargets is an enumeration that defines the following values:

• All, Assembly, Class, Constructor, Delegate, Enum, Event, Field, GenericParameter, Interface, Method, Module, Parameter, Property, ReturnValue, Struct

Page 19: Generic

• Two or more of these values can be ORed together. For example, to specify an attribute that can be applied only to fields and properties, use

• AttributeTargets.Field | AttributeTargets.Property

Page 20: Generic

• AttributeUsage supports two named parameters. The first is AllowMultiple, which is a bool value. If this value is true, then the attribute can be applied more than one time to a single item. The second is Inherited, which is also a bool value. If this value is true, then the attribute is inherited by derived classes. Otherwise, it is not inherited. The default setting is false for AllowMultiple and true for Inherited.

• AttributeUsage also specifies a read-only property called ValidOn, which returns a value of type AttributeTargets, which specifies what types of items the attribute can be used on. The default is AttributeTargets.All.

Page 21: Generic

The Conditional Attribute

• The attribute Conditional is perhaps C#’s most interesting built-in attribute. It allows you to create conditional methods. A conditional method is invoked only when a specific symbol has been defined via #define. Otherwise, the method is bypassed. Thus, a conditional method offers an alternative to conditional compilation using #if.

• Conditional is another name for System.Diagnostics.• ConditionalAttribute. To use the Conditional attribute,

you must include the System.Diagnostics namespace.

Page 22: Generic

• #define TRIAL• using System;• using System.Diagnostics;• class Test {• [Conditional("TRIAL")]• void Trial() {• Console.WriteLine("Trial version, not for distribution.");• }• [Conditional("RELEASE")]• void Release() {• Console.WriteLine("Final release version.");• }• static void Main() {• Test t = new Test();• t.Trial(); // called only if TRIAL is defined• t.Release(); // called only if RELEASE is defined• }• }

Page 23: Generic
Page 24: Generic

The Obsolete Attribute

• The Obsolete attribute, which is short for System.ObsoleteAttribute, lets you mark a program element as obsolete. Here is one of its forms:

[Obsolete(“message”)]

• Here, message is displayed when that program element is compiled. Here is a short example:

Page 25: Generic

• using System;• class Test {• [Obsolete("Use MyMeth2, instead.")]• public static int MyMeth(int a, int b) {• return a / b;• }• // Improved version of MyMeth.• public static int MyMeth2(int a, int b) {• return b == 0 ? 0 : a /b;• }• static void Main() {• // Warning displayed for this.• Console.WriteLine("4 / 3 is " + Test.MyMeth(4, 3));• // No warning here.• Console.WriteLine("4 / 3 is " + Test.MyMeth2(4, 3));• }• }