Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>C#</strong> .NET <strong>Migration</strong><br />
Moving from Visual Basic to <strong>C#</strong><br />
Jon Flanders<br />
jfland@develop.com<br />
Kirk Fertitta<br />
kirk@develop.com<br />
Jason Masterman<br />
jmasterman@develop.com<br />
Ted Pattison<br />
tedp@develop.com<br />
Doug Turnure<br />
dougt@develop.com<br />
Jason Whittington<br />
jasonw@develop.com<br />
Brought to you by<br />
Microsoft
News updates<br />
• #1 : Attendee toolkits will be sent to you in the mail<br />
– .NET t-shirts<br />
– More special edition books<br />
• #2: The “Slammer” Patch<br />
– http://www.microsoft.com/security/<br />
2
Agenda<br />
• The .NET Framework, The CLR and Obfuscation<br />
• Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
• Language Basics of <strong>C#</strong><br />
• Unique Features of <strong>C#</strong><br />
• Assembly Versioning and Deployment in the GAC<br />
• Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
• Start at 9:00 AM<br />
• Break 10:15 till 10:30<br />
• Lunch 12:00 – 1:00<br />
• Break 2:30 – 2:45<br />
• End at 4:00<br />
3
Developing with .NET<br />
• Three ways to get a development environment<br />
• 1 – Download the Framework SDK<br />
– http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.<br />
asp?url=/msdn-files/027/000/976/msdncompositedoc.xml&frame=true<br />
– FREE!<br />
– Does not include an IDE, use Notepad, EMACS, Ultra Edit, etc.<br />
• 2 – Visual Studio .NET<br />
– Comes with the Framework SDK<br />
– Includes a visual development environment<br />
– Not free<br />
– Beta version of VS.NET 2003 is also available and includes lots of new<br />
support for mobile devices<br />
• 3 – Windows Server 2003<br />
– Ships with the Framework included in the OS<br />
– No visual IDE<br />
4
Managed and Unmanaged Code<br />
Managed Code<br />
Unmanaged Code<br />
Managed Code<br />
(<strong>C#</strong>, VB.NET, etc.)<br />
Unmanaged Code<br />
(VB 6, C++, etc.)<br />
.NET Compiler<br />
Generated at compile time!<br />
Compiler<br />
CIL<br />
(Common Intermediate Language)<br />
x86 Machine Code<br />
CLR<br />
(Common Language Runtime)<br />
Depending on the version<br />
of the CLR different<br />
machine code can be<br />
generated.<br />
x86 Machine Code<br />
Generated at RUN time!<br />
5
The .NET Framework is a development platform<br />
• .NET Framework provides<br />
– Choice of several different language compilers<br />
– Debugger<br />
– Large number of Framework Class Libraries<br />
– Several different tools for inspection, security, deployment<br />
– Common Language Runtime (CLR) for Windows<br />
– Common Language Runtime for lightweight devices<br />
6
Why a Runtime?<br />
• MTS and COM+ were just better runtimes for COM objects<br />
– better threading support<br />
– better security<br />
– better transaction support<br />
• .NET is just another runtime<br />
– With a whole lot more added value<br />
– Much more open/exposed architecture<br />
– Huge class library<br />
– Better threading story<br />
– Better memory management story<br />
– Better deployment story – xcopy deployments<br />
– Better configuration story - No registry dependencies<br />
– Better security story – Based on components not process/threads<br />
7
Common Language Runtime<br />
• CLR is your new Runtime<br />
– In a way it’s like a new Operating System<br />
– It deals with memory layout<br />
– Provides your type system<br />
– Provides an additional layer of security<br />
– Provides a threading model<br />
– Provides ability to run code on other platforms<br />
• Knowing how the CLR works is they key to building applications<br />
with .NET<br />
8
Run on Any Platform<br />
• Today mainly Windows machines<br />
• Handheld devices are also supported<br />
• Rotor – Open Source Project for Linux and other platforms<br />
Your code<br />
Your code<br />
Framework Class Libraries<br />
Common Language Runtime (CLR)<br />
Operating System<br />
Hardware<br />
Server Computer<br />
Your code<br />
Framework Class Libraries<br />
Common Language Runtime (CLR)<br />
Operating System<br />
Hardware<br />
Desktop Computer<br />
Your code<br />
Framework Class Libraries<br />
Compact Framework (CF)<br />
Operating System<br />
Hardware<br />
Handheld device<br />
Windows XP Professional<br />
CF-compatible device<br />
Windows Server 2003<br />
9
Talk to Any Platform<br />
• Running code on any platform may be desirable<br />
• Running code that can talk to any platform is often more desirable<br />
Linux Server<br />
IBM Mainframe<br />
.NET Web Service Client<br />
Oracle DB<br />
Windows Server<br />
10
Platforms That Support .NET Framework<br />
• Client-side Windows platforms<br />
– Windows XP<br />
– Windows 2000<br />
– Windows NT<br />
– Windows 98/Windows ME<br />
• Server-side Windows platforms (ASP.NET)<br />
– Windows Server 2003<br />
– Windows 2000 Server<br />
– Windows XP – for development purposes<br />
• ASP.NET Helpful Install Utility<br />
– aspnet_regiis.exe /i will install ASP.NET on a machine after<br />
VS.NET was installed<br />
11
Many Languages – one runtime<br />
• All .NET languages compile to Common Intermediate Language<br />
VB.NET Source Code<br />
<strong>C#</strong> Source Code<br />
J# Source Code<br />
Managed C++<br />
VB.NET Compiler<br />
<strong>C#</strong> Compiler<br />
J# Compiler<br />
C++ Compiler<br />
MSIL Assembly<br />
With Metadata<br />
App.exe<br />
12
Concerns with MSIL<br />
• Easy to decompile!<br />
• Easy to see any hard coded database connection strings<br />
• How does one hide intellectual property, proprietary algorithms<br />
and such?<br />
13
Code Obfuscation<br />
• Not build into current release of VS .NET<br />
• Part of future release of VS .NET 2003<br />
14
Obfuscated Code<br />
//Original Source Code Before Obfuscation<br />
private void CalcPayroll(SpecialList employeeGroup)<br />
{<br />
while (employeeGroup.HasMore())<br />
{<br />
employee = employeeGroup.GetNext(true);<br />
employee.UpdateSalary();<br />
DistributeCheck(employee);<br />
}<br />
}<br />
//Reverse-Engineered Source Code<br />
//After Overload Induction Dotfuscation<br />
private void a(a b)<br />
{<br />
while (b.a())<br />
{<br />
a = b.a(true);<br />
a.a();<br />
a(a);<br />
}<br />
}<br />
15
Common Type System - CTS<br />
• The CLR defines the type system, CTS<br />
• All .NET languages map into the CTS<br />
• CLR types defined under the System Namespace<br />
• All .NET languages provide their own keywords that map to the<br />
underlying CTS types<br />
– <strong>C#</strong> int keyword == System.Int32<br />
– VB.NET integer keyword = System.Int32<br />
16
Common Type System (CTS)<br />
• CLR programming model is based on the CTS<br />
– CTS provides backbone for the CLR<br />
– CTS defines a core set of system types<br />
– CTS defines set of object-oriented programming features<br />
– CTS defines rules for creating user-defined types<br />
– all managed languages must map to the CTS<br />
17
Core CTS types<br />
• System.Object is root of type system<br />
– All types derive from Object<br />
– Some types treated special with regard to memory layout<br />
(ValueTypes)<br />
System-defined types<br />
User-defined types<br />
Object<br />
String Array ValueType Exception Delegate Class1<br />
Boolean<br />
Primitive types<br />
Single<br />
Enum<br />
Structure1<br />
Multicast<br />
Delegate<br />
Class2<br />
Byte<br />
Double<br />
Int16<br />
Decimal<br />
Enum1<br />
Delegate1<br />
Class3<br />
Int32<br />
DateTime<br />
Int64<br />
TimeSpan<br />
Char<br />
Guid<br />
18
Common Language Specification (CLS)<br />
• Ensures language interoperability<br />
• Defines a subset of the CTS<br />
• Most of the Framework Class Libraries are CLS compliant<br />
• Cannot overload based on return type<br />
• Unsigned integral types are not allowed on public methods<br />
• Can use the CLSCompliantAttribute to enforce checks<br />
19
CLSCompliantAttribute<br />
using System;<br />
// Assembly marked as compliant.<br />
[assembly: CLSCompliantAttribute(true)]<br />
// Class marked as compliant.<br />
[CLSCompliantAttribute(true)]<br />
public class MyCompliantClass<br />
{<br />
// ChangeValue exposes UInt32, which is not in CLS.<br />
// A compile-time error results.<br />
public void Method1(UInt32 var)<br />
{<br />
}<br />
//not a problem because scope is local to app<br />
internal void Method2(UInt32 var)<br />
{<br />
}<br />
//tell compiler to ignore CSLCompliant<br />
//attribute for this method<br />
[CLSCompliant(false)]<br />
public void Method3(UInt32 var)<br />
{<br />
}<br />
}<br />
20
<strong>C#</strong> Types – extend CLS Types<br />
• Comprehensive set of simple types available<br />
Type<br />
Description<br />
Special format for literals<br />
Boolean<br />
bool<br />
Boolean<br />
true false<br />
character<br />
char<br />
16 bit Unicode character<br />
'A' '\x0041' '\u0041'<br />
sbyte<br />
8 bit signed integer<br />
none<br />
byte<br />
8 bit unsigned integer<br />
none<br />
short<br />
16 bit signed integer<br />
none<br />
integer<br />
ushort<br />
int<br />
16 bit unsigned integer<br />
32 bit signed integer<br />
none<br />
none<br />
uint<br />
32 bit unsigned integer<br />
U suffix<br />
long<br />
64 bit signed integer<br />
L or l suffix<br />
ulong<br />
64 bit unsigned integer<br />
U/u and L/l suffix<br />
float<br />
32 bit floating point<br />
F or f suffix<br />
floating point<br />
double<br />
64 bit floating point<br />
no suffix<br />
decimal<br />
128 bit high precision<br />
M or m suffix<br />
string<br />
string<br />
character sequence<br />
"hello"<br />
21
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
• Language Basics of <strong>C#</strong><br />
• Unique Features of <strong>C#</strong><br />
• Assembly Versioning and Deployment in the GAC<br />
• Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
22
<strong>C#</strong> and VB.NET – not as different as you might think<br />
• Both have:<br />
– Support structured exception handling<br />
– Support for Interfaces<br />
– Support for Inheritance<br />
– Support for virtual functions<br />
– Support for static functions<br />
– Support for method overloading<br />
– Support for constructors/destructors<br />
– Support for indexers<br />
– Support FCL<br />
23
Class Basics<br />
public class Human{<br />
}<br />
public int Age;<br />
public string Name;<br />
public void Speak(){<br />
}<br />
Console.WriteLine(“Name:{0} Age:{1}",Name,Age);<br />
Simple class with public<br />
fields for properties<br />
Client code working with<br />
Human classes<br />
class Client<br />
{<br />
static void Main(string[] args)<br />
{<br />
Human h = new Human();<br />
h.Age = 21;<br />
h.Name = "Rian Brandell";<br />
}<br />
}<br />
24
Properties<br />
public class Human<br />
{<br />
private int m_Age;<br />
public int Age<br />
{<br />
set<br />
{<br />
if (value > 0)<br />
{<br />
m_Age = value;<br />
}<br />
else<br />
{<br />
}<br />
}<br />
A better way of exposing<br />
data members, through a<br />
public property and<br />
private field for storage<br />
throw new ArgumentOutOfRangeException("Age invalid");<br />
}<br />
}<br />
get{return m_Age;}<br />
25
Interfaces<br />
• Interfaces are an explicit kind of type in the CLR<br />
– Express what is common across classes<br />
– Allow classes to share a common design<br />
– Include sufficient type information to program against, but not<br />
enough to instantiate<br />
– Members may include methods, properties, indexers, and events<br />
– Cannot include implementation details or fields<br />
– Concrete type must supply all implementation details<br />
26
Implementing and using interfaces<br />
using System;<br />
interface ICowboy<br />
{<br />
void Draw();<br />
string Name { get; }<br />
object this[int n] { get; }<br />
}<br />
Console.WriteLine(cb.Name);<br />
class Rancher : ICowboy<br />
{<br />
public void Draw() { Console.WriteLine("Bang!"); }<br />
public string Name { get { return("Tex"); } }<br />
public object this[int n] { get { return(...); } }<br />
}<br />
Using the interfaces<br />
class Wrangler : ICowboy<br />
{<br />
public void Draw() { Console.WriteLine("Bang!"); }<br />
public string Name { get { return("Woody"); } }<br />
public object this[int n] { get { return(...); } }<br />
}<br />
ICowboy cb = new Rancher();<br />
cb.Draw();<br />
Console.WriteLine(cb.Name);<br />
cb = new Wrangler();<br />
cb.Draw();<br />
Declaring and implementing the interfaces<br />
27
Type compatibility and navigation<br />
• <strong>C#</strong> supports typical type compatibility<br />
– Types may implement multiple interfaces<br />
– A class must declare which interface it supports<br />
• The CLR supports explicit runtime type navigation<br />
– An object is type-compatible with interface X if and only if the<br />
object's class supports interface X<br />
– <strong>C#</strong> is, as, and typecast operators support explicit run-time type<br />
navigation<br />
28
Using Type Navigation Operators<br />
interface ICowboy {}<br />
interface IArtist {}<br />
class Tex : ICowboy {}<br />
class LaRoche : IArtist {}<br />
// What happens if DrawAndPaint is passed<br />
// a Tex or LaRoche instance?<br />
//<br />
void DrawAndPaint( object o )<br />
{<br />
// InvalidCastException on failure:<br />
IArtist a = (IArtist)o;<br />
a.Paint();<br />
// False on failure:<br />
bool IsArmed = o is ICowboy;<br />
Using explicit cast, is and as<br />
operations to perform type navigation<br />
}<br />
// Null reference on failure:<br />
ICowboy cb = o as ICowboy;<br />
if( cb != null )<br />
{<br />
cb.Draw();<br />
}<br />
29
Explicit interface implementation<br />
interface ICowboy { void Draw(); }<br />
interface IArtist { void Draw(); }<br />
class LaTex : ICowboy, IArtist<br />
{<br />
}<br />
Implementation is not marked public<br />
so the only way to get to the<br />
implementation is through the<br />
interface<br />
void ICowboy.Draw() { Console.WriteLine("Bang!"); }<br />
void IArtist.Draw() { Console.WriteLine("Brush, brush"); }<br />
LaTex starvingDrifter = new LaTex();<br />
starvingDrifter.Draw(); // Compiler error - no public Draw()<br />
ICowboy cb = starvingDrifter;<br />
cb.Draw(); // Bang!<br />
IArtist a = starvingDrifter;<br />
a.Draw();<br />
// Brush, brush<br />
30
Base classes<br />
• Every type has at most one base type<br />
– System.Object and interfaces have no base type<br />
– System.Enum for enums, System.Array for arrays<br />
– Base type for classes defaults to System.Object if not explicitly<br />
specified<br />
– sealed class modifier prevents use as a base type<br />
– abstract class modifier mandates derivation<br />
31
Specifying a base class in <strong>C#</strong><br />
public class MyClassName : BaseImpl, Itf1, Itf2<br />
{<br />
// member definitions go here<br />
}<br />
Name of base type<br />
List of supported interfaces<br />
32
Base/derived construction<br />
• Constructors and base types have "issues"<br />
– Base type constructors not part of derived type's signature<br />
– Base type constructors must be called from derived constructors<br />
using C++-like syntax<br />
– Overloaded constructor on self can be called using C++-like<br />
syntax<br />
– Base type's constructor executes using the most-derived type (like<br />
Java, not C++)<br />
– Waterfall construction model for <strong>C#</strong> allows derived members to be<br />
accessed prior to initialization<br />
33
Base types and constructors<br />
interface IPerson {...}<br />
interface ICowboy {...}<br />
public class PersonImpl : IPerson<br />
{<br />
public PersonImpl(string name) {...}<br />
public PersonImpl(string name, int age) {...}<br />
}<br />
public class Cowboy : PersonImpl, ICowboy<br />
{<br />
public Cowboy(string n, int a ) : base(n, a) {...}<br />
public Cowboy(string n) : base(n) {...}<br />
public Cowboy() : this("Tex", 34) {}<br />
public void Draw() {...}<br />
}<br />
Chain call to base types constructor<br />
34
Derivation and constructor flow of control<br />
D3..ctor()<br />
g()<br />
D2..ctor<br />
e()<br />
D1..ctor<br />
c()<br />
Base..ctor()<br />
a()<br />
b()<br />
d()<br />
public class Base {<br />
public int x = a();<br />
public Base() { b(); }<br />
}<br />
public class D1 : Base {<br />
public int y = c();<br />
public D1() { d(); }<br />
}<br />
public class D2 : D1 {<br />
public int z = e();<br />
public D2() { f(); }<br />
}<br />
public class D3 : D2 {<br />
public int w = g();<br />
public D3() { h(); }<br />
}<br />
f()<br />
h()<br />
35
<strong>C#</strong> method dispatching modifiers<br />
From the perspective of a base class designer<br />
<strong>C#</strong> Syntax<br />
virtual<br />
abstract<br />
sealed<br />
Meaning<br />
Method may be replaced by derived class.<br />
Method must be replaced by a derived class (or redeclared abstract).<br />
Method may not be replaced by a derived class.<br />
From the perspective of a derived class designer<br />
<strong>C#</strong> Syntax<br />
Meaning<br />
override<br />
new<br />
Method replaces a virtual/abstract/override method in the base with its own<br />
implementation, and is still overridable by further derived types.<br />
Method is unrelated to a similarly defined method in the base class. Typically<br />
used to deal with a change to a base class that creates a collision where one<br />
didn't exist before, and where it's not practical to just choose a different method<br />
name.<br />
36
Using method dispatching modifiers<br />
abstract class Base<br />
{<br />
public void a() {} // statically bound, cannot override<br />
public virtual void b() {} // may be overridden<br />
public abstract void c(); // must override or redeclare abstract<br />
public virtual void d() {} // may be overridden<br />
}<br />
class Derived : Base<br />
{<br />
public override void a() {} // illegal: Base.a not overridable<br />
public override void b() {} // legal: Base.b override allowed<br />
public override void c() {} // legal: Base.c override required<br />
public new void d() {} // unrelated to Base.d, not overridable<br />
}<br />
class MoreDerived : Derived<br />
{<br />
public override void c() {} // legal: Derived.c still overridable<br />
}<br />
37
Combining method dispatching modifiers<br />
Method modifer combinations<br />
<strong>C#</strong> Syntax<br />
sealed override<br />
new virtual<br />
new abstract<br />
Meaning<br />
This method replaces a virtual/abstract/override method in the base with its own<br />
implementation, and terminates the overridability of this method as far as further<br />
derived types are concerned.<br />
This method is unrelated to a similarly defined method in the base class and<br />
gets a new slot in the associated virtual method dispatching table for this class.<br />
Further derived types may choose to override this method.<br />
This method is unrelated to a similarly defined method in the base class and<br />
gets a new slot in the associated virtual method dispatching table for this class.<br />
Further derived types must to override this method.<br />
38
Combining method modifiers<br />
abstract class Base<br />
{<br />
public void a() {} // statically bound, cannot override<br />
public virtual void b() {} // may be overridden<br />
public abstract void c(); // must override or redeclare abstract<br />
public virtual void d() {} // may be overridden<br />
}<br />
abstract class Derived : Base<br />
{<br />
public sealed override void b() {} // terminal override of Base.b<br />
public new virtual void d() {} // unrelated to Base.d, overridable<br />
}<br />
class MoreDerived : Derived<br />
{<br />
public override void b() {} // illegal: Derived.b sealed<br />
public override void c() {} // overrides Base.c<br />
public override void d() {} // overrides Derived.d<br />
}<br />
39
Destructors<br />
• Implemented by defining a method via ~ClassName, like C++<br />
• Not called directly by your code<br />
• Called by the Garbage Collector when needed<br />
• Often desirable to have cleanup code run before GC runs<br />
– Implement IDisposable interface<br />
– Called by client when done using object<br />
40
Destructors and IDisposable<br />
using System;<br />
class Class1<br />
{<br />
static void Main(string[] args)<br />
{<br />
Widget wg = new Widget();<br />
Console.WriteLine(wg.ToString());<br />
wg.Dispose(); //specific call to cleanup<br />
wg = null; //let go of reference and wait for GC<br />
Console.ReadLine();<br />
}<br />
}<br />
public class Widget : IDisposable<br />
{<br />
~Widget()<br />
{<br />
Destructor called by GC<br />
}<br />
//cleanup code called by GC<br />
}<br />
public void Dispose()<br />
{<br />
//perform cleanup<br />
}<br />
Dispose called by client!<br />
41
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
• Unique Features of <strong>C#</strong><br />
• Assembly Versioning and Deployment in the GAC<br />
• Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
42
Culturally Very Different ;-)<br />
• <strong>C#</strong> is much a more disciplined/strict language than VB.NET<br />
– Case sensitive<br />
– No “Option Explicit Off” for variable declarations<br />
– No “Option Strict Off” for strict type checking<br />
– Required to initialize variables before use<br />
– Targeted towards C++ and Java developer<br />
– Not hard to switch too if coming from VB though<br />
43
Unique <strong>C#</strong> Features<br />
• Native support for Unsigned integral types<br />
• Operator overloading<br />
• Using statement<br />
– Ensures IDisposable.Dispose is called<br />
• Unsafe code blocks<br />
– Mainly used to support API’s that require pointers<br />
• Documentation Comments<br />
– Used to generate XML or HTML documentation<br />
• Strict type checking is on and can’t be turned off<br />
– VB.NET has Option Strict on/off with Off being the default<br />
44
Operator Overloading<br />
using System;<br />
class Client{<br />
static void Main(string[] args){<br />
Point p1 = new Point();<br />
p1.x = 10; p1.y=10;<br />
Point p2 = new Point();<br />
p2.x = 10; p2.y=10;<br />
Point p3 = p1 + p2;<br />
Console.WriteLine("p3.x:{0} p3.y:{1}",p3.x,p3.y);<br />
}<br />
}<br />
class Point{<br />
public int x;<br />
public int y;<br />
public static Point operator+(Point p1, Point p2){<br />
Point p = new Point();<br />
p.x = p1.x + p2.x;<br />
p.y = p1.y + p2.y;<br />
return p;<br />
}<br />
}<br />
Use the operator keyword<br />
and whichever operator<br />
you wish to overload<br />
45
Using Statement<br />
using System;<br />
Using statement causes<br />
class Class1<br />
automatic call to Dispose<br />
{<br />
to be generated at<br />
static void Main(string[] args)<br />
compile time<br />
{<br />
using(DataBaseManager dbm = new DataBaseManager())<br />
{<br />
//use dbm<br />
}<br />
}<br />
}//Dispose method of dbm called automatically!<br />
public class DataBaseManager : IDisposable<br />
{<br />
void IDisposable.Dispose()<br />
{<br />
//database cleanup code<br />
}<br />
}<br />
46
Unsafe Code Blocks<br />
• Must set compiler option in project properties<br />
– Project->Properties->Configuration Properties->Build->Allow<br />
Unsafe Code blocks – set to true<br />
[DllImport("kernel32", SetLastError=true)]<br />
static extern unsafe bool ReadFile(int hFile,<br />
void* lpBuffer, int nBytesToRead,<br />
int* nBytesRead, int overlapped);<br />
Marked as Unsafe due to<br />
pointers<br />
public unsafe int Read(byte[] buffer, int index, int count)<br />
{<br />
}<br />
int n = 0;<br />
fixed (byte* p = buffer)<br />
{<br />
}<br />
return n;<br />
ReadFile(handle, p + index, count, &n, 0);<br />
Marked fixed to keep<br />
object from moving when<br />
GC runs<br />
47
Documentation Comments<br />
• Just type “///” above a method and VS.NET does the rest!<br />
• Project->Properties->Configuration Properties->Build->XML<br />
Documentation Path<br />
• Tools->Build Comment Web Pages…<br />
• Generates XML and HTML page for viewing<br />
/// <br />
/// Class for managing checking account<br />
/// <br />
public class Checking{<br />
/// <br />
/// Called to make a deposit<br />
/// <br />
/// <br />
/// <br />
public int MakeDeposit(int amount){<br />
}<br />
}<br />
48
Documentation Comments-Output<br />
49
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
Unique Features of <strong>C#</strong><br />
• Assembly Versioning and Deployment in the GAC<br />
• Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
50
Assemblies and Versioning<br />
• Assemblies by default are not strong named<br />
• Assemblies without strong name are not versionable<br />
• Must learn how to give an assembly a strong name<br />
• Requires knowledge of some other tools<br />
• Versioned assemblies can be installed in the Global Assembly<br />
Cache – via “gacutil.exe –i yourassembly.dll”<br />
• Strong Named assemblies include:<br />
– Name<br />
– Version<br />
– Culture<br />
– Public Key Token<br />
51
Generating Strong Named Assembly<br />
• A strong named assembly must have:<br />
– Name, version, culture and public key token<br />
– By default culture is “neutral”, which is a valid value if not specified<br />
• Steps involved<br />
– Add Key attributes to your code<br />
• AssemblyVersion<br />
• AssemblyKeyFile<br />
– Generate key file with “sn.exe –k mykey.snk”<br />
– Compile code<br />
using System;<br />
using System.Reflection;<br />
[assembly: AssemblyVersion("1.0.0.0")]<br />
[assembly: AssemblyDelaySign(false)]<br />
[assembly: AssemblyKeyFile("..\\..\\mykey.snk")]<br />
class TheLibrary{<br />
public void Method1()<br />
{<br />
//implementation<br />
}<br />
}<br />
Version number<br />
Assembly key file<br />
generated with sn.exe<br />
tool<br />
52
Assembly without strong name<br />
Notice lack of version<br />
number and public key<br />
53
Client referencing weak assembly<br />
Notice version number<br />
and key for strong name<br />
assembly<br />
Notice lack of version<br />
number and public key<br />
54
Assembly with strong name<br />
Notice version number<br />
and public key<br />
55
Client referencing strong named assembly<br />
Notice version number<br />
and public key<br />
56
Client and Versioning<br />
• Client is compiled to version 1.0.0.0 of assembly<br />
• What happens if we need client to use version 2.0.0.0 of<br />
assembly?<br />
• We don’t want to recompile the client –<br />
– Use application configuration file<br />
– Redirect client to new version in configuration file<br />
57
Client.exe.config for assembly redirect<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Assembly redirect to<br />
newer version. No need<br />
to recompile client!<br />
58
Global Assembly Cache<br />
• One of the first places searched for matching assembly by the<br />
assembly resolver<br />
• Similar to the registry but very different<br />
• Only strong named assemblies can be placed in the GAC<br />
• Very helpful for shared assemblies<br />
Our assembly installed in<br />
the GAC<br />
59
Publisher policy<br />
• Shared component “publishers” can automate version<br />
redirection for their assemblies<br />
– deployed as XML configuration files embedded in separate<br />
assemblies<br />
– “policy assembly” itself must be installed in the GAC<br />
– one policy assembly per major/minor version number<br />
– policy....dll<br />
– applications can disable publisher-driven version redirects<br />
• application-wide<br />
• per-publisher<br />
60
Creating a publisher policy assembly<br />
acme.cs (new version 1.0.0.1)<br />
using System.Reflection;<br />
[assembly: AssemblyKeyFile("acme.snk")]<br />
[assembly: AssemblyVersion("1.0.0.1")]<br />
csc /t:library acme.cs<br />
acme.dll (new version 1.0.0.1)<br />
acme.dll.config<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
acme.snk<br />
Installed in the GAC on target machines<br />
al.exe /link:acme.dll.config<br />
/out:policy.1.0.acme.dll<br />
/keyf:acme.snk<br />
/v:1.0.0.0<br />
policy.1.0.acme.dll<br />
61
Disabling publisher policy for a given publisher<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
62
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
Unique Features of <strong>C#</strong><br />
Assembly Versioning and Deployment in the GAC<br />
• Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
63
Delegates<br />
• Provide a very loosely coupled notification/callback mechanism<br />
• Class based references are tightly coupled<br />
• Interfaces are better but still have drawbacks<br />
– Must implement entire interface<br />
– May not be interested in all method notifications defined in the<br />
interface<br />
• Delegates are the smallest piece of an interface<br />
– A single method signature<br />
– Events are based on delegates<br />
– Can use delegates for asynchronous programming<br />
– Important aspect of .NET development to understand<br />
• Great article on delegates<br />
– http://www.sellsbrothers.com/writing/default.aspx?content=delegat<br />
es.htm<br />
64
Pattern<br />
• Notification typically involves registration and callback<br />
– target registers with caller<br />
– caller calls back target when state changes<br />
– pattern also called publish/subscribe<br />
Parent<br />
(target)<br />
register<br />
callback<br />
Student<br />
(caller)<br />
65
Delegates<br />
• .NET Framework uses delegates to implement callbacks<br />
– intermediary between caller and target<br />
– declaration defines callback method signature<br />
– instance stores object reference and method token<br />
target<br />
object<br />
target<br />
method<br />
callback<br />
delegate<br />
callback<br />
caller<br />
66
Delegate definition<br />
• Define delegate with delegate keyword<br />
– syntax similar to method declaration without body<br />
– delegate name placed where method name usually goes<br />
delegate keyword<br />
name of created delegate<br />
delegate void GradeChange(double gpa);<br />
callback method<br />
return type<br />
callback method<br />
parameter<br />
67
Delegate as type<br />
• Delegate name used as type name<br />
– can declare references<br />
– can create objects<br />
define delegate<br />
delegate void GradeChange(double gpa);<br />
GradeChange g = new GradeChange(...);<br />
reference<br />
object<br />
68
Target use of delegate<br />
• Target defines method with signature specified by delegate<br />
– parameters and return type must match<br />
– method name not constrained<br />
delegate defines<br />
required signature<br />
target<br />
method signature<br />
matches delegate<br />
delegate void GradeChange(double gpa);<br />
class Parent<br />
{<br />
public void Report(double gpa)<br />
{<br />
...<br />
}<br />
}<br />
69
Caller use of delegate<br />
• Caller typically defines delegate reference<br />
caller<br />
delegate reference<br />
class Student<br />
{<br />
public GradeChange Targets;<br />
...<br />
}<br />
70
Registration<br />
• Create delegate object and store in caller to register<br />
– pass target object and method to delegate constructor<br />
caller<br />
target<br />
create<br />
void Run()<br />
{<br />
Student ann = new Student("Ann");<br />
Parent mom = new Parent();<br />
GradeChange g = new GradeChange(mom.Report);<br />
store<br />
}<br />
ann.Targets = g;<br />
...<br />
target<br />
object<br />
target<br />
method<br />
71
Invocation<br />
• Caller invokes callback indirectly through delegate<br />
– uses method call syntax on delegate<br />
– delegate calls target method on target object<br />
class Student<br />
{<br />
public GradeChange Targets;<br />
invoke callback<br />
through delegate<br />
}<br />
public void RecordClass(int grade)<br />
{<br />
// update gpa<br />
...<br />
Targets(gpa);<br />
}<br />
callback takes<br />
double argument<br />
72
Summary of delegate use<br />
define delegate<br />
target method<br />
caller stores delegate<br />
delegate void GradeChange(double gpa);<br />
class Parent<br />
{<br />
public void Report(double gpa) { ... }<br />
}<br />
class Student<br />
{<br />
public GradeChange Targets;<br />
caller invokes delegate<br />
}<br />
public void RecordClass(int grade)<br />
{<br />
// update gpa<br />
...<br />
Targets(gpa);<br />
}<br />
Student ann = new Student("Ann");<br />
Parent mom = new Parent();<br />
create and install delegate<br />
ann.Targets = new GradeChange(mom.Report);<br />
ann.RecordClass(4); // 4 == 'A'<br />
73
Multiple targets<br />
• Can combine delegates using operator+= or operator+<br />
– creates invocation list of delegates<br />
– all targets called when delegate invoked<br />
– targets called in order added<br />
– use of += ok even when left-hand-side is null<br />
targets<br />
Parent mom = new Parent();<br />
Parent dad = new Parent();<br />
Student ann = new Student("Ann");<br />
first<br />
second<br />
ann.Targets += new GradeChange(mom.Report);<br />
ann.Targets += new GradeChange(dad.Report);<br />
...<br />
74
Remove delegate<br />
• Can remove delegate from invocation list<br />
– use operator-= or operator-<br />
– target object and method identity determines which is removed<br />
Parent mom = new Parent();<br />
Parent dad = new Parent();<br />
Student ann = new Student("Ann");<br />
add<br />
remove<br />
ann.Targets += new GradeChange(mom.Report);<br />
ann.Targets += new GradeChange(dad.Report);<br />
...<br />
ann.Targets -= new GradeChange(dad.Report);<br />
...<br />
target<br />
object<br />
target<br />
method<br />
75
Public delegate<br />
• Not common to have public delegate field<br />
– allows assignment: could overwrite existing registrants<br />
– allows external invocation: decision should be made internally<br />
public delegate<br />
overwrite mom handler<br />
invoke<br />
class Student<br />
{<br />
public GradeChange Targets;<br />
...<br />
}<br />
Parent mom = new Parent();<br />
Parent dad = new Parent();<br />
Student ann = new Student("Ann");<br />
...<br />
ann.Targets = new GradeChange(mom.Report);<br />
ann.Targets = new GradeChange(dad.Report);<br />
...<br />
ann.Targets(4.0);<br />
...<br />
76
Events<br />
• Events give private data/public accessor pattern for delegates<br />
– created by applying event keyword to delegate<br />
– external code can uses += and -=<br />
– no external assignment or invocation<br />
event<br />
class Student<br />
{<br />
public event GradeChange Targets;<br />
...<br />
}<br />
Parent mom = new Parent();<br />
Student ann = new Student("Ann");<br />
ok to use +=<br />
error to use =<br />
error to invoke<br />
ann.Targets += new GradeChange(mom.Report);<br />
ann.Targets = new GradeChange(mom.Report);<br />
ann.Targets(4.0);<br />
...<br />
77
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
Unique Features of <strong>C#</strong><br />
Assembly Versioning and Deployment in the GAC<br />
Windows Forms and why you need to get Delegates and Events<br />
• Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
78
Interoperability<br />
• Framework Class Libraries is what counts<br />
• Most of learning .NET is in the FCL!<br />
• Not all things possible with managed FCL classes<br />
• May need to call COM or C style DLL’s<br />
– COM interoperability works very well from any .NET language<br />
– P/Invoke works well for C style DLL’s with few limitations<br />
Three flavors of interoperability<br />
• Two for calling legacy code<br />
– COM interoperability (COM Interop)<br />
– Platform Invoke (P/Invoke)<br />
• One for calling .NET from Legacy Code<br />
– .NET Interoperability with COM clients<br />
79
COM Interoperability<br />
• Must deal with type transitions in/out of the runtime<br />
• Requires Interoperability assembly<br />
• Interoperability assembly generated two ways<br />
– VS.NET Add Reference – easily generates interop assembly<br />
– TLBIMP.EXE utility – allow fine grain control over interop<br />
assembly<br />
80
Using a VB6 DLL from <strong>C#</strong> .NET<br />
• CLR-to-COM interaction made possible by interop assemblies<br />
– interop assembly is a managed shim DLL that wraps a COM DLL<br />
– .NET client programs against managed types in interop assembly<br />
– CLR uses interop assembly at runtime to create/call COM objects<br />
• How do you create an interop assembly?<br />
– using a .NET SDK Framework utility named TLBIMP.EXE<br />
– using Visual Studio .NET<br />
Assembly Manifest<br />
dependent assembly list<br />
Type library<br />
interface _Class1<br />
coclass Class1<br />
executable x86 instructions<br />
TLBIMP.EXE<br />
Assembly Manifest<br />
Managed Type Information<br />
interface _Class1<br />
class Class1<br />
class Class1Class<br />
mscorlib<br />
Microsoft.VisualBasic<br />
Interop.BobsLibrary<br />
MyApp.exe<br />
BobsLibrary.dll<br />
Interop.BobsLibrary.dll<br />
81
Creating an interop assembly with VS.NET<br />
• Visual Studio .NET can build the interop assembly for you<br />
– use COM tab in project's Add Reference dialog<br />
– VS.NET cannot build an interop assembly with a strong name<br />
82
Platform Invoke - P/Invoke<br />
• P/Invoke is the technology that allows managed code to call out<br />
to unmanaged code<br />
– LoadLibrary/GetProcAddress automated using static methods<br />
marked extern<br />
– Can control all aspects using DllImport attribute<br />
– No call to LoadLibrary until first invocation (a la delay load)<br />
– Unicode/ANSI issues handled explicitly or automatically based on<br />
platform<br />
83
Using P/Invoke<br />
using System.Runtime.InteropServices;<br />
InteropServices namespace<br />
public class K32Wrapper<br />
{<br />
[ DllImport("kernel32.dll") ]<br />
public extern static void Sleep(uint msec);<br />
DllImport attribute<br />
[ DllImport("kernel32.dll", EntryPoint = "Sleep") ]<br />
public extern static void Doze(uint msec);<br />
[ DllImport("user32.dll") ]<br />
public extern static uint MessageBox(int hwnd, String m,<br />
String c, uint flags);<br />
[<br />
DllImport("user32.dll", EntryPoint="MessageBoxW",<br />
ExactSpelling=true, CharSet=CharSet.Unicode)<br />
]<br />
public extern static uint UniBox(int hwnd, String m,<br />
String c, uint flags);<br />
}<br />
84
MarshalAsAttribute parameters<br />
• Controlling type transitions out of the runtime<br />
• Done via MarshalAsAttribute<br />
Parameter Name<br />
Value<br />
ArraySubType<br />
SafeArraySubType<br />
SizeConst<br />
SizeParamIndex<br />
MarshalType<br />
MarshalCookie<br />
Type<br />
UnmanagedType<br />
UnmanagedType<br />
VarType<br />
int<br />
short<br />
String<br />
String<br />
Description<br />
Unmanaged type to marshal to (mandatory)<br />
Unmanaged type of array elements<br />
Unmanaged VARTYPE of safearray elements<br />
Fixed size of unmanaged array<br />
Index of parameter containing [size_is] value<br />
Fully-qualified type name of custom marshaler<br />
Cookie for custom marshaler<br />
85
Using MarshalAs on parameters<br />
using System.Runtime.InteropServices;<br />
public class FooBarWrapper<br />
{<br />
// this routine wraps a native function declared as<br />
// void _stdcall DoIt(LPCWSTR s1, LPCSTR s2,<br />
// LPTSTR s3, BSTR s4);<br />
}<br />
[ DllImport("foobar.dll") ]<br />
public static extern void DoIt(<br />
[MarshalAs(UnmanagedType.LPWStr)] String s1,<br />
[MarshalAs(UnmanagedType.LPStr)] String s2,<br />
[MarshalAs(UnmanagedType.LPTStr)] String s3,<br />
[MarshalAs(UnmanagedType.BStr)] String s4<br />
);<br />
Controlling type<br />
transitions out of the<br />
runtime via MarshalAs<br />
attribute<br />
86
.NET Interoperability with COM<br />
• In the real world you will also need to expose your .NET<br />
components to COM clients<br />
• TLBEXP.EXE can export .NET info to COM type libraries<br />
• REGASM.EXE will add .NET information to registry and generate<br />
COM type libraries<br />
interface IPatient {}<br />
interface IBillee {}<br />
struct ORGAN {}<br />
class American:<br />
IPatient, IBillee {}<br />
TLBEXP.EXE<br />
TLBIMP.EXE<br />
interface IPatient :<br />
IDispatch {}<br />
interface IBillee :<br />
IDispatch {}<br />
struct ORGAN {}<br />
interface _American :<br />
IDispatch {}<br />
coclass American {<br />
_American,<br />
IPatient, IBillee<br />
}<br />
mycsharpcode.dll<br />
mycsharpcode.tlb<br />
87
REGASM<br />
• The SDK provides a tool to make managed types available to<br />
COM's CoCreateInstance<br />
– TLBIMP makes COM classes available to CLR via new operator<br />
– REGASM adds COM registry entries for all CLR classes in an<br />
assembly<br />
– MSCOREE registered as actual InprocServer32<br />
– Can suppress exposure using ComVisible or<br />
NoComRegistration attributes<br />
– Can write custom class factory if desired<br />
– Use REGASM /codebase for assemblies not in GAC<br />
88
.NET Exposed for COM Clients<br />
using System;<br />
public interface IMath<br />
{<br />
int Add(int x, int y);<br />
int Subtract(int x, int y);<br />
}<br />
// After building run: regasm /codebase /tlb Calc.dll<br />
public class Calc : IMath<br />
{<br />
public int Add(int x, int y) { return x + y; }<br />
public int Subtract(int x, int y) { return x - y; }<br />
}<br />
89
The Registry after REGASM<br />
• Registry entries for .NET component<br />
Notice that the registry<br />
points to mscoree.dll and<br />
it loads the calc.dll<br />
90
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
Unique Features of <strong>C#</strong><br />
Assembly Versioning and Deployment in the GAC<br />
Windows Forms and why you need to get Delegates and Events<br />
Interoperability – COM/Win32<br />
• Writing data access code with ADO.NET<br />
91
ADO.NET<br />
• ADO.NET shipped with two class hierarchies<br />
– One that is 100% managed for working with SQL Server<br />
– One that provides managed objects over any existing unmanaged<br />
provider<br />
– Other managed providers exist now!<br />
ADO.NET<br />
OleDbCommand<br />
SqlCommand<br />
OleDbConnection<br />
SqlConnection<br />
Unmanaged Providers<br />
TDS Parser - managed<br />
92
ADO.NET Example<br />
public static void UseDataReader()<br />
{<br />
SqlConnection conn = new<br />
SqlConnection("server=localhost;database=pubs;trusted_connection=true");<br />
SqlCommand cmd = new SqlCommand("select * from authors",conn);<br />
conn.Open();<br />
IDataReader rdr = cmd.ExecuteReader();<br />
while (rdr.Read())<br />
{<br />
}<br />
}<br />
Console.WriteLine(rdr["au_lname"]);<br />
int col = rdr.GetOrdinal("au_lname");<br />
Console.WriteLine(rdr[col]);<br />
Console.WriteLine(rdr.GetString(col));<br />
SqlConnection and<br />
SqlCommand<br />
IDataReader is used for<br />
reading data via an<br />
underlying stream<br />
93
DataSets<br />
• Provides a disconnected model<br />
• In memory representation similar to a Recordset<br />
• Not dependent on any specific resource manager!<br />
• Can be bound to controls<br />
• Provides easy edit and update functionality<br />
Oracle<br />
SQL Server<br />
OracleDataAdapter<br />
SqlDataAdapter<br />
XML Data<br />
DataSet<br />
DataSet is a stand alone<br />
data store!<br />
Active Directory<br />
DataAdapter<br />
Exchange<br />
DataAdapter<br />
Active Directory<br />
Exchange<br />
94
DataSet Example<br />
public static void UseDataSet()<br />
{<br />
SqlConnection conn = new<br />
SqlConnection("server=localhost;database=pubs;trusted_connection=true");<br />
SqlCommand cmd = new SqlCommand("select * from authors",conn);<br />
SqlDataAdapter da = new SqlDataAdapter(cmd);<br />
DataSet ds = new DataSet();<br />
}<br />
da.Fill(ds);<br />
ds.WriteXml(Console.Out,System.Data.XmlWriteMode.IgnoreSchema);<br />
DataAdapter executes<br />
statement and pours<br />
results into the dataset<br />
DataAdapter is also<br />
smart enough to open the<br />
connection if needed and<br />
close it when finished<br />
95
Agenda<br />
The .NET Framework and the CLR<br />
Common Type System (CTS) and Common Language<br />
Specification (CLS)<br />
Language Basics of <strong>C#</strong><br />
Unique Features of <strong>C#</strong><br />
Assembly Versioning and Deployment in the GAC<br />
Windows Forms and why you need to get Delegates and Events<br />
Interoperability – COM/Win32<br />
Writing data access code with ADO.NET<br />
96
Call to Action<br />
• Must master Framework Class Libraries<br />
• Many aspects to explore in more detail<br />
• Language is the easy part<br />
• ASP.NET will be next!<br />
• Take a look at the new platform - Windows Server 2003<br />
– Many improvements, especially with IIS<br />
97
Useful URLs<br />
• http://portals.devx.com/SummitDays<br />
– valuable .NET resources including Ted's sample chapter<br />
• http://msdn.microsoft.com/net<br />
– valuable .NET resources from Microsoft<br />
• http://www.develop.com<br />
– Information about instructor-led training from DevelopMentor<br />
– http://discuss.develop.com – one the best list servers for .NET<br />
information on the web<br />
• http://www.jmasterman.com/isvtour<br />
– PDF version of slides and zip file of samples/labs<br />
98