Tải bản đầy đủ - 0 (trang)
3-9. Unload Assemblies and Application Domains

3-9. Unload Assemblies and Application Domains

Tải bản đầy đủ - 0trang

CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



3-10. Retrieve Type Information

Problem

You need to obtain a System.Type object that represents a specific type.



Solution

Use one of the following:





The typeof operator







The static GetType method of the System.Type class







The GetType method of an existing instance of the type







The GetNestedType or GetNestedTypes method of the Type class







The GetType or GetTypes method of the Assembly class







The GetType, GetTypes, or FindTypes method of the System.Reflection.Module

class



How It Works

The Type class provides a starting point for working with types using reflection. A Type object allows you

to inspect the metadata of the type, obtain details of the type’s members, and create instances of the

type. Because of its importance, the .NET Framework provides a variety of mechanisms for obtaining

references to Type objects.

One method of obtaining a Type object for a specific type is to use the typeof operator shown here:

System.Type t1 = typeof(System.Text.StringBuilder);

The type name is not enclosed in quotes and must be resolvable by the compiler (meaning you must

reference the assembly using a compiler switch). Because the reference is resolved at compile time, the

assembly containing the type becomes a static dependency of your assembly and will be listed as such in

your assembly’s manifest.

An alternative to the typeof operator is the static method Type.GetType, which takes a string

containing the type name. Because you use a string to specify the type, you can vary it at runtime, which

opens the door to a world of dynamic programming opportunities using reflection (see recipe 3-12). If

you specify just the type name, the runtime must be able to locate the type in an already loaded

assembly. Alternatively, you can specify an assembly-qualified type name. Refer to the .NET Framework

SDK documentation for the Type.GetType method for a complete description of how to structure

assembly-qualified type names. Table 3-2 summarizes some other methods that provide access to Type

objects.



125



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



Table 3-2. Methods That Return Type Objects



Method



Description



Type.GetNestedType



Gets a specified type declared as a nested type within the existing Type object.



Type.GetNestedTypes



Gets an array of Type objects representing the nested types declared within the

existing Type object.



Assembly.GetType



Gets a Type object for the specified type declared within the assembly.



Assembly.GetTypes



Gets an array of Type objects representing the types declared within the

assembly.



Module.GetType



Gets a Type object for the specified type declared within the module. (See recipe

1-3 for a discussion of modules.)



Module.GetTypes



Gets an array of Type objects representing the types declared within the module.



Module.FindTypes



Gets a filtered array of Type objects representing the types declared within the

module. The types are filtered using a delegate that determines whether each

Type should appear in the final array.



The Code

The following example demonstrates how to use typeof and the GetType method to return a Type object

for a named type and from existing objects:

using System;

using System.Text;

namespace Apress.VisualCSharpRecipes.Chapter03

{

class Recipe03_10

{

public static void Main()

{

// Obtain type information using the typeof operator.

Type t1 = typeof(StringBuilder);

Console.WriteLine(t1.AssemblyQualifiedName);

// Obtain type information using the Type.GetType method.

// Case-sensitive, return null if not found.

Type t2 = Type.GetType("System.String");

Console.WriteLine(t2.AssemblyQualifiedName);



126



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



// Case-sensitive, throw TypeLoadException if not found.

Type t3 = Type.GetType("System.String", true);

Console.WriteLine(t3.AssemblyQualifiedName);

// Case-insensitive, throw TypeLoadException if not found.

Type t4 = Type.GetType("system.string", true, true);

Console.WriteLine(t4.AssemblyQualifiedName);

// Assembly-qualifed type name.

Type t5 = Type.GetType("System.Data.DataSet,System.Data," +

"Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089");

Console.WriteLine(t5.AssemblyQualifiedName);

// Obtain type information using the Object.GetType method.

StringBuilder sb = new StringBuilder();

Type t6 = sb.GetType();

Console.WriteLine(t6.AssemblyQualifiedName);

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter.");

Console.ReadLine();

}

}

}



3-11. Test an Object’s Type

Problem

You need to test the type of an object.



Solution

Use the inherited Object.GetType method to obtain a Type for the object. You can also use the is and as

operators to test an object’s type.



How It Works

All types inherit the GetType method from the Object base class. As discussed in recipe 3-10, this method

returns a Type reference representing the type of the object. The runtime maintains a single instance of

Type for each type loaded, and all references for this type refer to this same object. This means you can

compare two type references efficiently. For convenience, C# provides the is operator as a quick way to

check whether an object is a specified type. In addition, is will return true if the tested object is derived

from the specified class.

Both of these approaches require that the type used with the typeof and is operators be known and

resolvable at compile time. A more flexible (but slower) alternative is to use the Type.GetType method to



127



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



return a Type reference for a named type. The Type reference is not resolved until runtime, which causes

the performance hit but allows you to change the type comparison at runtime based on the value of a

string.

Finally, you can use the as operator to perform a safe cast of any object to a specified type. Unlike a

standard cast, which triggers a System.InvalidCastException if the object cannot be cast to the specified

type, the as operator returns null. This allows you to perform safe casts that are easy to verify, but the

compared type must be resolvable at runtime.



■ Note The runtime will usually maintain more than one instance of each type depending on how assemblies are

loaded into application domains. Usually, an assembly will be loaded into a specific application domain, meaning a

Type instance will exist in each application domain in which the assembly is loaded. However, assemblies can also

be loaded by a runtime host in a domain-neutral configuration, which means the assembly’s type metadata (and

Type instances) is shared across all application domains. By default, only the mscorlib assembly is loaded in a

domain-neutral configuration.



The Code

The following example demonstrates the various type-testing alternatives described in this recipe:

using System;

using System.IO;

namespace Apress.VisualCSharpRecipes.Chapter03

{

class Recipe03_11

{

// A method to test whether an object is an instance of a type

// or a derived type.

public static bool IsType(object obj, string type)

{

// Get the named type, use case-insensitive search, throw

// an exception if the type is not found.

Type t = Type.GetType(type, true, true);

return t == obj.GetType() || obj.GetType().IsSubclassOf(t);

}

public static void Main()

{

// Create a new StringReader for testing.

Object someObject = new StringReader("This is a StringReader");



128



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

3-9. Unload Assemblies and Application Domains

Tải bản đầy đủ ngay(0 tr)

×