Visual Basic 1002005 [A Developers Notebook] [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Visual Basic 1002005 [A Developers Notebook] [Electronic resources] - نسخه متنی

شرکت رسانه او ریلی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







2.5. Build Typesafe Generic Classes




Programmers often face a difficult
choice. On one hand, it's keenly important to build
solutions that are as generic as possible, so that they can be reused
in different scenarios. For example, why build a
CustomerCollection class that accepts only objects
of type Customer when you can build a generic
Collection class that can be configured to accept
objects of any type? On the other hand, performance and type safety
considerations can make a generic solution less desirable. If you use
a generic .NET Collection class to store
Customer objects, for example, how can you be sure
that someone won't accidentally insert another type
of object into the collection, causing an insidious problem later on?


Note: Need to create a class that's flexible
enough to work with any type of object, but able to restrict the
objects it accepts in any given instance? With generics, VB has the
perfect solution.



Visual Basic 2005 and .NET 2.0 provide a solution called
generics. Generics are classes that are
parameterized by type. In other words, generics
allow you to create a class template that supports any type. When you
instantiate that class, you specify the type you want to use, and
from that point on, your object is "locked
in" to the type you chose.


2.5.1. How do I do that?


An example of where the use of generics makes great sense is the
System.Collections.ArrayList class.

ArrayList is an
all-purpose, dynamically self-sizing collection. It can hold ordinary
.NET objects or your own custom objects. In order to support this,
ArrayList treats everything as the base
Object type.

The problem is that there's no way to impose any
restrictions on how ArrayList works. For example,
if you want to use ArrayList to store a collection
of Customer objects, you have no way to be sure
that a faulty piece of code won't accidentally
insert strings, integers, or some other type of object, causing
future headaches. For this reason, developers often create their own
strongly typed collection classesin fact, the .NET class
library is filled with dozens of them.

Generics can solve this problem. For example, using generics you can
declare a class that works with any type using the
Of keyword:

Public Class GenericList(Of ItemType)
' (Code goes here)
End Class

In this case, you are creating a new class named
GenericList that can work with any type of object.
However, the client needs to specify what type should be used. In
your class code, you refer to that type as
ItemType. Of course, ItemType
isn't really a typeit's just
a placeholder for the type that you'll choose when
you instantiate a GenericList object.

Example 2-2 shows the complete code for a simple
typesafe ArrayList.


Example 2-2. A typesafe collection using generics

Public Class GenericList(Of ItemType)
Inherits CollectionBase
Public Function Add(ByVal value As ItemType) As Integer
Return List.Add(value)
End Function
Public Sub Remove(ByVal value As ItemType)
List.Remove(value)
End Sub
Public ReadOnly Property Item(ByVal index As Integer) As ItemType
Get
' The appropriate item is retrieved from the List object and
' explicitly cast to the appropriate type, and then returned.
Return CType(List.Item(index), ItemType)
End Get
End Property
End Class

The GenericList class wraps an ordinary
ArrayList, which is provided through the
List property of the
CollectionBase class it inherits from. However,
the GenericList class works differently than an
ArrayList by providing strongly typed
Add( ) and Remove( ) methods,
which use the ItemType placeholder.

Here's an example of how you might use the
GenericList class to create an
ArrayList collection that only supports strings:

' Create the GenericList instance, and choose a type (in this case, string).
Dim List As New GenericList(Of String)
' Add two strings.
List.Add("blue")
List.Add("green")
' The next statement will fail because it has the wrong type.
' There is no automatic way to convert a GUID to a string.
' In fact, this line won't ever run, because the compiler
' notices the problem and refuses to build the application.
List.Add(Guid.NewGuid( ))

There's no limit to how many ways you can
parameterize a class. In the GenericList example,
there's only one type parameter. However, you could
easily create a class that works with two or three types of objects,
and allows you to make all of these types generic. To use this
approach, just separate each parameter type with a comma (between the
brackets at the beginning of a class).

For example, consider the following
GenericHashTable class, which allows you to define
the type of the items the collection will store
(ItemType), as well as the type of the keys you
will use to index those items (KeyType):

Public Class GenericHashTable(Of ItemType, KeyType)
Inherits DictionaryBase
' (Code goes here.)
End Class

Another important feature in generics is the ability to apply
constraints to parameters. Constraints restrict
the types allowed for a given generic class. For example, suppose you
want to create a class that supports only types that implement a
particular interface. To do so, first declare the type or types the
class accepts and then use the As keyword to
specify the base class that the type must derive from, or the
interface that the type must implement.

Here's an example that restricts the items stored in
a GenericList to serializable items. This feature
would be useful if, for example, you wanted to add a method to the
GenericList that required serialization, such as a
method that writes all the items in the list to a stream:

Public Class SerializableList(Of ItemType As ISerializable)
Inherits CollectionBase
' (Code goes here.)
End Class

Similarly, here's a collection that can contain any
type of object, provided it's derived from the
System.Windows.Forms.Control class. The end result
is a collection that's limited to controls, like the
one exposed by the Forms.Controls property on a
window:

Public Class ControlCollection(Of ItemType As Control)
Inherits CollectionBase
' (Code goes here.)
End Class

Sometimes, your generic class might need the ability to create the
parameter class. For example, the GenericList
example might need the ability to create an instance of the item you
want to store in the collection. In this case, you need to use the
New constraint. The New
constraint allows only parameter types that have a public
zero-argument constructor, and aren't marked
MustInherit. This ensures that your code can
create instances of the parameter type. Here's a
collection that imposes the New constraint:

Public Class GenericList(Of ItemType As New)
Inherits CollectionBase
' (Code goes here.)
End Class

It's also worth noting that you can define as many
constraints as you want, as long as you group the list of constraints
in curly braces, as
shown here:

Public Class GenericList(Of ItemType As {ISerializable, New})
Inherits CollectionBase
' (Code goes here.)
End Class

Constraints are enforced by the compiler, so if you violate a
constraint rule when using a generic class, you
won't be able to compile your application.


Note: Generics are built into the Common Language Runtime. That
means they are supported in all first-class . NET languages,
including C#.




2.5.2. What about...


...using generics with other code structures? Generics
don't just work with classes.


They can also be used in structures,
interfaces, delegates, and even methods. For more information, look
for the index entry "generics" in
the MSDN Help. For more in-depth examples of advanced generic
techniques, you can refer to a Microsoft whitepaper at http://www.msdn.net/library/en-us/dnvs05/html/vb2005_generics.asp.

Incidentally, the .NET Framework designers are well aware of the
usefulness of generic collections, and they've
already created several for you to use out of the box.
You'll find them in the new
Systems.Collections.Generic
namespace. They include:

List (a basic collection like the
GenericList example)

Dictionary (a name-value collection that indexes
each item with a key)

LinkedList (a linked list, where each item points
to the next item in the chain)

Queue (a first-in-first-out collection)

Stack (a last-in-first-out collection)

SortedList (a name-value collection
that's kept in perpetually sorted order)


Most of these types duplicate one of the types in the
System.Collections namespace. The old collections
remain for backward compatibility.


/ 97