Advanced .NET Framework Topics

basiliskcanoeΛογισμικό & κατασκευή λογ/κού

2 Νοε 2013 (πριν από 3 χρόνια και 8 μήνες)

64 εμφανίσεις


All types in the CLR are self
-
describing


CLR provides a reader and writer for type
definitions


System.Reflection & System.Reflection.emit


You can ‘read’ programs


You can map between type systems


You can interrogate objects and types inside a
running program

Reflection Overview

Execution model

Cobol

VB

C++

C#

CIL code

(+ metadata)

Loader/verifier

Managed Code

Uncompiled

method call

Execution

Language compilers

.NET

languages

JIT compiler

Reflection

Core Concepts


Metadata


Single location for type information and code


Code is literally contained within type information


Every .NET object can be queried for its type


Type metadata can be explored with Reflection


Dynamic Type System


Highly dynamic and language independent


Types may be extended and built at run time


Allows on
-
the
-
fly creation of assemblies


See my
CodeDom

tutorial

http://www.codeproject.com/KB/dotnet/CodeDomDelegates.aspx


Metadata uses


Allows type developed in a PL to be used by
code in other PL


GC uses to traverse objects


Serialization (essential for Web Services)


IDE (e.g. IntelliSense)

Exploring Metadata


Who are you?


What are you?


Anything special about you?


Now tell me what you have!


Types and Instances

System.Type


Access to meta
-
data for any .NET type


Returned by System.Object.GetType()


Allows drilling down into all facets of a type


Category: Simple, Enum, Struct or Class


Methods and Constructors, Parameters and
Return


Fields and Properties, Arguments and Attributes


Events, Delegates and Namespaces


C# also has the,
typeof
(),
is

and
as

operators.

What are you?


Value, Interface or Class?


IsValueType, IsInterface, IsClass


Public, Private or Sealed ?


IsNotPublic, IsSealed


Abstract or Implementation?


IsAbstract


Covers all possible properties of a managed
type


Very intuitive API, no "Parameter Hell"

Type Reflection

Object

IEnquire

IPrint

ITransfer

Account

Savings

Savings.BaseType ==Account

Savings.BaseType.BaseType == Object

ITransfer.BaseType ==
null

Account.IsSubClassof(IEnquire) ==
false

Savings.IsSubClassof(Account) ==
true

Savings.GetInterfaces() ==


{ IPrint, ITransfer, IEnquire }

IEnquire.IsAssignableFrom(Savings) ==
true




Reflection and the CLR type system

System.Object

EventInfo

PropertyInfo

FieldInfo

MethodBase

System.Type

ParameterInfo

MemberInfo

Module

Assembly

MethodInfo

ConstructorInfo

MetaData: Type Info at Runtime

[serializable]

public class Person :

{


public event OnSaveChange onsv;


public Date DOB;


public string FirstName;


public string LastName;


public string Name {


get {


return FirstName + " " + LastName;


}


}


public Person(string First,string Last)


{


FirstName=First;LastName=Last;


}


public bool Save()


{


System.Type t = this
.GetType()
;


foreach( FieldInfo f in t.GetFields() )


{ ... }


}

System.Type

Attributes

Fields

Properties

Constructors

Methods

Events

Parameters

Reflection

MetaData Samples

// Test sample class

public class
Test {


private int
n;


public

Test(
int

a) { n=a;}


public

void

Foo(
float

a,
object

b,
string

c) { }

}


//Retrieve the Type object

public static int
Main(
string
[] args) {


Type type1 =
typeof
(Test);


Test t1 =
new

Test(0);


Type type2 = t1.
GetType
();


Console.WriteLine
(
“type of t1 is {0}”
, type2);


return

0

}

Note:

type1==type2

ReferenceEquals(type1, type2) ==
true

Reflection

Type and Instances


Type Safety First! Type checking at run time


if (o is Customer) { … }


Dynamic Invocation through Reflection


Support for late binding:


MethodInfo.Invoke
()


FieldInfo
.SetValue()

Reflection

GetMethods

Example

//Get a list of methods supported by a class

public static int Main(string[] args) {


Type type1 =
typeof
(Test);


MethodInfo
[]
minf

= type1.
GetMethods
();


foreach

(
MethodInfo

m in
minf
) {


//Print out the method name and whether it is public


Console.WriteLine
(“Name: “+
m.Name

+ “,” +


((
m.IsPublic
) ? “ public” : “”) + ((
m.IsVirtual
) ? “virtual” : “”);


//Get the list of parameters


ParameterInfo
[] pi =
m.GetParameters
();


foreach

(
ParameterInfo

p in pi)


Console.WriteLine
(“ “ +
p.ParameterType

+ “ “ +
p.Name
);


}


return 0

}

Name: Foo, public


System.Single a


System.Object b


System.String c

Name: GetType, public

Name: ToString, public virtual

Name: Equals, public virtual


System.Object obj

Name: GetHashCode, public virtual

Press any key to continue . . .

Reflection

MemberInfo


Base class for all "member" element descriptions


Fields, Properties, Methods, etc.


Provides member kind, name, and declaring class

MemberInfo

MethodBase

ParameterInfo

FieldInfo

EventInfo

PropertyInfo

MethodInfo

ConstructorInfo

Anything special about you?


Special Memory Layout?


IsAutoLayout


IsExplicitLayout


IsLayoutSequential


COM Objects?


IsCOMObject


More…


IsUnicodeClass


IsSpecialName
, etc.

Now tell me what you have!


Finding and Exploring Members


MemberInfo: GetMembers(), FindMembers()


Exploring Fields and Properties


FieldInfo: GetFields(), PropertyInfo: GetProperties()


Exploring Constructors, Methods and Events


GetConstructors(), GetMethods(), GetEvents()


Exploring attributes, determining implemented
interfaces, enumerating nested types, …


Summary: Everything you may ever want to know

Type and Instances


Type Safety First! Type checking at runtime


C#:
if (o is Customer) { … }


VB:
If TypeOf o Is Customer Then …
End If


Dynamic Invocation through Reflection


Support for late binding


MethodInfo.Invoke()


FieldInfo.SetValue()


PropertyInfo.SetValue()

Reflection

Dynamic Creation Example


You can use CreateInstance and other methods
to create instances at run
-
time and call their
methods and properties.


See the example
here
for more info.


http://www.csharp
-
examples.net/reflection
-
examples/

Reflection

The Bigger Picture


Types know their module; modules know their types


Modules know their assembly and vice versa


Code can browse and search its entire context

Assembly

Module

Module

Module

Class

Struct

Constructor

Method

Method

Field

Class

Interface

Class

Delegate

Class

Interface

Interface

Traverse every element in an assembly

Using System.Reflection;

public static void WalkAssembly(String assemblyName)

{


Assembly assembly = Assembly.Load (assemblyName);


foreach (Module module in assembly.GetModules())


foreach (Type type in module.GetTypes())


foreach (MemberInfo member in type.GetMembers())


Console.WriteLine (

{0}.{1}

, type, member.Name;

}

Object Creation


OK, now see my CodeDom tutorial

http://www.codeproject.com/KB/dotnet/CodeDomDelegates.aspx



Serialization


Save state of an object on disk or send to a
stream (we will cover this more later):


public class Point : {


public double x;


public double y;


public double length; // computed from x, y

};

Solutions


Inherit from a base type:

class Point : Serializable { … }

but …


base type does not know derived type


requires multiple inheritance


Java solution:

class Point implements Serializable { … }

but …


method granularity


customization requires full rewrite of WriteObject,
ReadObject

Solution: Attributes

[Serializable]

public class Point : {


public double x;


public double y;


[NonSerialized]


public double length; // computed from x, y

};

Reflection

Summary


Reflection = System.Type + GetType()


Explore type information at runtime


Enables attribute
-
driven programming


Bottom line: Fully self
-
contained structural model



Used extensively in Visual Studio

VisualStudio.NET and Reflection

Component Class

Description

DefaultValue

Help

Localizable

ReadOnly

ComponentMode
l Attributes

Toolbox

Properties
Window

Designers

Help

System.AddIn


There is a new set of classes in the
System.AddIn

namespace for aiding in plug
-
in architectures.


I have not had a chance to look at this closely, but
it appears to be more for creating Adapter’s (see
the Adapter design pattern) and creating a
common interface (called an
IContract
). In other
words allowing a plug
-
in that did not support
your interface in the first place.


See
http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/08/13/Build
-
AddIns
-
with
-
System
-
AddIn.aspx
.