DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

42
DEV300: Advanced C# DEV300: Advanced C# Eric Gunnerson Eric Gunnerson Program Manager Program Manager Visual C# Visual C# Microsoft Corporation Microsoft Corporation

Transcript of DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Page 1: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

DEV300: Advanced C#DEV300: Advanced C#

Eric GunnersonEric GunnersonProgram ManagerProgram ManagerVisual C#Visual C#Microsoft CorporationMicrosoft Corporation

Page 2: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.
Page 3: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and tricksLanguage tips and tricks InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 4: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and tricksLanguage tips and tricks InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 5: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A Data Type Of Your OwnA Data Type Of Your Own

A type that hasA type that has Operator OverloadingOperator Overloading User-defined conversionsUser-defined conversions XML DocumentationXML Documentation PropertiesProperties

A type like Decimal…A type like Decimal…

Page 6: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Reference Or Value type?Reference Or Value type?

Data types all have value semanticsData types all have value semantics val1 = val2val1 = val2 means copy value, not make means copy value, not make

val1 point at val2val1 point at val2

Value type is the right choice unlessValue type is the right choice unless The type is of variable size (like string)The type is of variable size (like string) The type is big (> 16ish bytes)The type is big (> 16ish bytes)

Reference types must be immutableReference types must be immutable Methods don’t modify valueMethods don’t modify value Methods return new instanceMethods return new instance Like string typeLike string type

Page 7: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Two Data TypesTwo Data Types

demodemo

Page 8: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Intro To AnimationIntro To Animation

To animate a ball, we need to track:To animate a ball, we need to track: Position (a point)Position (a point) Velocity (a vector)Velocity (a vector)

Each frame, add velocity to positionEach frame, add velocity to position

Handle collisions as necessaryHandle collisions as necessary

Page 9: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Collision With A CircleCollision With A Circle

c

v

vcV

vc = c * (c · v / |c|2)

v = ball velocity

v = v – vc * 2

Vector c = new Vector(center, position);Float dot = Vector.DotProduct(c, v);Float len = c.Length;Vector vc = c * (dot / (len * len));v = v - vc * 2;

c = center to ball center

Page 10: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and tricksLanguage tips and tricks InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 11: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Deterministic FinalizationDeterministic Finalization

Means “you know exactly when an Means “you know exactly when an object is destroyed”object is destroyed”

You want itYou want it You can’t have itYou can’t have it

A very complicated discussionA very complicated discussion See See http://www.gotdotnet.com/team/csharp/informationhttp://www.gotdotnet.com/team/csharp/information

Look for article on Resource managementLook for article on Resource management

Page 12: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Object DestructionObject Destruction

Two main issues:Two main issues: Garbage collection means non-Garbage collection means non-

deterministic finalizationdeterministic finalization GC chooses:GC chooses:

When objects are destroyedWhen objects are destroyed Order of destructionOrder of destruction

Garbage collector can’t clean up Garbage collector can’t clean up unmanaged objectsunmanaged objects

Page 13: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

SolutionSolution

Cleanup at GC timeCleanup at GC time Objects with unmanaged Objects with unmanaged

resources implement a finalizer resources implement a finalizer to free those resourcesto free those resources

Early CleanupEarly Cleanup Objects implement IDisposable, Objects implement IDisposable,

users call Dispose() to clean upusers call Dispose() to clean up

Page 14: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Scenario 1Scenario 1User Calls Dispose()User Calls Dispose()

Unmanaged Unmanaged ResourceResource

Font objectFont object

Dispose()Dispose()

Dispose()Dispose()

freefreeIntPtr IntPtr myResource;myResource;

Font font;Font font;

Dispose() means free my resources, and Dispose() means free my resources, and call Dispose() on any contained objectscall Dispose() on any contained objects

Page 15: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Scenario 2Scenario 2Object Finalized by GCObject Finalized by GC

Unmanaged Unmanaged ResourceResource

Font objectFont object

Finalize()Finalize()

Dispose()?Dispose()?

freefreeIntPtr IntPtr myResource;myResource;

Font font;Font font;

Finalize() means free my resources only; Finalize() means free my resources only; other managed resources will also get other managed resources will also get finalizedfinalized

XX

Finalize()Finalize()

Page 16: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Implementing IDisposableImplementing IDisposable

Design pattern for early cleanupDesign pattern for early cleanup Only required when you:Only required when you:

Wrap unmanaged resourcesWrap unmanaged resources You’ll need a destructor tooYou’ll need a destructor too

OROR Need to be able to clean up earlyNeed to be able to clean up early

Not required for the vast majority Not required for the vast majority of objectsof objects

Page 17: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

DestructorsDestructors

Object.Finalize is not accessible in C#Object.Finalize is not accessible in C#

public class Resource: IDisposablepublic class Resource: IDisposable{{ ~Resource() {...}~Resource() {...}}}

public class Resource: IDisposablepublic class Resource: IDisposable{{ protected override void Finalize() {protected override void Finalize() { try {try { ...... }} finally {finally { base.Finalize();base.Finalize(); }} }}}}

Page 18: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Doing The ImplementationDoing The Implementationpublic class Resource: IDisposablepublic class Resource: IDisposable{{ IntPtr myResource;IntPtr myResource; Font font;Font font;

protected virtual void Dispose(bool disposing) {protected virtual void Dispose(bool disposing) { if (disposing) {if (disposing) { font.Dispose();font.Dispose(); GC.SuppressFinalize(this);GC.SuppressFinalize(this); }} FreeThatResource(myResource);FreeThatResource(myResource); }} public void Dispose() {public void Dispose() { Dispose(true);Dispose(true); }} ~Resource() {~Resource() { Dispose(false);Dispose(false); }}}}

Page 19: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Using StatementUsing Statement

Acquire, Execute, Release patternAcquire, Execute, Release pattern Works with any IDisposable objectWorks with any IDisposable object

Data access classes, streams, text readers Data access classes, streams, text readers and writers, network classes, etc.and writers, network classes, etc.

using (Resource res = new Resource()) {using (Resource res = new Resource()) { res.DoWork();res.DoWork();}}

Resource res = new Resource(...);Resource res = new Resource(...);try {try { res.DoWork();res.DoWork();}}finally {finally { if (res != null) ((IDisposable)res).Dispose();if (res != null) ((IDisposable)res).Dispose();}}

Page 20: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Using StatementUsing Statement

static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName);Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName);Stream output = File.Create(destName); byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} output.Close();output.Close(); input.Close();input.Close();}}

static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName);Stream input = File.OpenRead(sourceName); try {try { Stream output = File.Create(destName);Stream output = File.Create(destName); try {try { byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} }} finally {finally { output.Close();output.Close(); }} }} finally {finally { input.Close();input.Close(); }}}}

static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { using (Stream input = File.OpenRead(sourceName))using (Stream input = File.OpenRead(sourceName)) using (Stream output = File.Create(destName)) {using (Stream output = File.Create(destName)) { byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} }}}}

Page 21: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and tricksLanguage tips and tricks InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 22: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

VersioningVersioning

What happens when base components What happens when base components are changed? are changed?

Versioning an important design goalVersioning an important design goal Virtual methods and overridingVirtual methods and overriding Overload resolutionOverload resolution Explicit interface implementationExplicit interface implementation Const vs. readonly fieldsConst vs. readonly fields Defaults for accessibility and virtualityDefaults for accessibility and virtuality

Page 23: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Versioning: OverridingVersioning: Overriding

class Derived: Baseclass Derived: Base // version 1// version 1{{ public virtual void Foo() {public virtual void Foo() { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }}}}

class Derived: Baseclass Derived: Base // version 2a// version 2a{{ newnew public virtual void Foo() { public virtual void Foo() { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }}}}

class Derived: Baseclass Derived: Base // version 2b// version 2b{{ public public overrideoverride void Foo() { void Foo() { base.Foo();base.Foo(); Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }}}}

class Baseclass Base // version 1// version 1{{}}

class Base class Base // version 2 // version 2 {{ public virtual void Foo() {public virtual void Foo() { Console.WriteLine("Base.Foo"); Console.WriteLine("Base.Foo"); }}}}

Page 24: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Versioning: OverloadingVersioning: Overloading

public class Basepublic class Base // version 1// version 1{{}}

public class Derived: Basepublic class Derived: Base // version 1// version 1{{ public void Add(double x) {...}public void Add(double x) {...}}}

Derived d = new Derived(...);Derived d = new Derived(...);d.Add(1);d.Add(1);

public class Basepublic class Base // version 2// version 2{{ public void Add(int x) {...}public void Add(int x) {...}}}

Page 25: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Versioning: InterfacesVersioning: Interfaces

interface IGraphics {interface IGraphics { void Draw();void Draw(); Brush Brush { get; set; }Brush Brush { get; set; } Pen Pen { get; set; }Pen Pen { get; set; }}}

interface IBandit {interface IBandit { void Draw();void Draw(); void Duel(IBandit opponent);void Duel(IBandit opponent); void Rob(Bank bank, IBandit[] sidekicks);void Rob(Bank bank, IBandit[] sidekicks);}}

class Bandit: IGraphics {class Bandit: IGraphics { public void Draw() {...}public void Draw() {...}}}

class Bandit: IGraphics, IBandit {class Bandit: IGraphics, IBandit { public void Draw() {...} // Which interface?public void Draw() {...} // Which interface?}}

class Bandit: IBandit, IGraphics {class Bandit: IBandit, IGraphics { public void Draw() {...}public void Draw() {...} void IGraphics.Draw() {...}void IGraphics.Draw() {...}}}

class Bandit: IBandit, IGraphics {class Bandit: IBandit, IGraphics { void IBandit.Draw() {...}void IBandit.Draw() {...} void IGraphics.Draw() {...}void IGraphics.Draw() {...}}}

Page 26: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and tricksLanguage tips and tricks InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 27: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Definite AssignmentDefinite Assignment

A variable must be definitely assigned A variable must be definitely assigned before its value can be obtainedbefore its value can be obtained

Auto-initialized vs. unassignedAuto-initialized vs. unassigned Static flow analysis looks at all Static flow analysis looks at all

possible execution pathspossible execution paths

static int Mumble(int flags) {static int Mumble(int flags) { int n;int n; if (flags != 0){if (flags != 0){ n = Something();n = Something(); }} return n;return n;}}

Page 28: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

void printf(string fmt, object[] args) {void printf(string fmt, object[] args) { foreach (object x in args) {foreach (object x in args) { ...... }}}}

void printf(string fmt, void printf(string fmt, paramsparams object[] args) { object[] args) { foreach (object x in args) {foreach (object x in args) { ...... }}}}

object[] args = new object[3];object[] args = new object[3];args[0] = str;args[0] = str;args[1] = int1;args[1] = int1;args[2] = int2;args[2] = int2;printf("%s %i %i", args);printf("%s %i %i", args);

printf("%s %i %i", str, int1, int2);printf("%s %i %i", str, int1, int2);

object[] args = new object[3];object[] args = new object[3];args[0] = str;args[0] = str;args[1] = int1;args[1] = int1;args[2] = int2;args[2] = int2;printf("%s %i %i", args);printf("%s %i %i", args);

Parameter ArraysParameter Arrays

Methods with a variable Methods with a variable number of parametersnumber of parameters

Page 29: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Ref And Out ParametersRef And Out Parameters

Use “ref” for in/out parameter passingUse “ref” for in/out parameter passing Use “out” to return multiple valuesUse “out” to return multiple values Must repeat ref/out at call siteMust repeat ref/out at call site

static void Swap(ref int a, ref int b) {...}static void Swap(ref int a, ref int b) {...}

static void Divide(int dividend, int divisor,static void Divide(int dividend, int divisor, out int result, out int remainder) {...}out int result, out int remainder) {...}

static void Main() {static void Main() { int x = 1, y = 2;int x = 1, y = 2; Swap(ref x, ref y);Swap(ref x, ref y);}}

Page 30: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Is, As, And Typeof OperatorsIs, As, And Typeof Operators

Check if a conversion will succeedCheck if a conversion will succeed

Perform exception-free conversionPerform exception-free conversion

Get System.Type object for a typeGet System.Type object for a type

if (o is string) {if (o is string) { string s = (string)o;string s = (string)o; LogString(s);LogString(s);}}

string s = o as string;string s = o as string;if (s != null) Console.WriteLine(s);if (s != null) Console.WriteLine(s);

if (o.GetType() == typeof(string))if (o.GetType() == typeof(string)) Console.WriteLine("o is a string");Console.WriteLine("o is a string");

Page 31: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Overflow CheckingOverflow Checking

Integer arithmetic operationsInteger arithmetic operations C, C++, Java silently overflowC, C++, Java silently overflow

checked vs. unchecked contextchecked vs. unchecked context Default is unchecked, except for Default is unchecked, except for

constantsconstants Change with “/checked” compiler switchChange with “/checked” compiler switch

int i = checked(x * y);int i = checked(x * y);

checked {checked { int i = x * y;int i = x * y;}}

Page 32: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Throw StatementThrow Statement

Throw exception:Throw exception: throw e;throw e; Re-throw exception:Re-throw exception: throw;throw;

try {try { DoSomething();DoSomething();}}catch (Exception e) {catch (Exception e) { LogError(...);LogError(...); throw;throw;}}

Page 33: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Foreach StatementForeach Statement Iteration of arraysIteration of arrays

Iteration of IEnumerable collectionsIteration of IEnumerable collections

foreach (Account a in Bank.GetAccounts(...)) {foreach (Account a in Bank.GetAccounts(...)) { if (a.Balance < 0) Console.WriteLine(a.CustName);if (a.Balance < 0) Console.WriteLine(a.CustName);}}

public static void Main(string[] args) {public static void Main(string[] args) { foreach (string s in args) Console.WriteLine(s);foreach (string s in args) Console.WriteLine(s);}}

Page 34: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Foreach StatementForeach Statement

Can be modified with user-written Can be modified with user-written classesclasses

See my December 2001 column for See my December 2001 column for more informationmore information http://www.gotdotnet.com/team/csharp/informationhttp://www.gotdotnet.com/team/csharp/information

foreach (string s in new IterReverse(names))foreach (string s in new IterReverse(names)){...}{...}

foreach (DateTime t in new IterSort(times))foreach (DateTime t in new IterSort(times)){...}{...}

Page 35: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Lock StatementLock Statement

Use lock for mutual exclusionUse lock for mutual exclusion Protect member vars from other threadsProtect member vars from other threads

Use typeof as lock for static methodsUse typeof as lock for static methodsclass Cacheclass Cache{{ ArrayList objects = new ArrayList();ArrayList objects = new ArrayList(); public void Add(object x) {public void Add(object x) { lock (this) {lock (this) { objects.Add(x);objects.Add(x); }} }}

public static Cache Create() {public static Cache Create() { lock(typeof(Cache)) {...}lock(typeof(Cache)) {...} } } }}

Page 36: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

A data type of your very ownA data type of your very own Deterministic finalizationDeterministic finalization VersioningVersioning Language tips and trick or treatLanguage tips and trick or treat InteroperabilityInteroperability

Advanced C# TopicsAdvanced C# Topics

Page 37: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Unsafe CodeUnsafe Code

When pointers are a necessityWhen pointers are a necessity Advanced COM and P/Invoke interopAdvanced COM and P/Invoke interop Existing binary structuresExisting binary structures Performance extremesPerformance extremes

Low-level code without leaving the boxLow-level code without leaving the box Basically “inline C”Basically “inline C”

Page 38: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

struct COFFHeader {struct COFFHeader { public ushort MachineType;public ushort MachineType; public ushort NumberOfSections;public ushort NumberOfSections; … … public ushort Characteristics;public ushort Characteristics;}}

private COFFHeader fileHeader;private COFFHeader fileHeader;

void ReadHeader(BinaryStream InFile)void ReadHeader(BinaryStream InFile){{ fileHeader.MachineType = inFile.ReadUInt16();fileHeader.MachineType = inFile.ReadUInt16(); fileHeader.NumberOfSections = inFile.ReadUInt16();fileHeader.NumberOfSections = inFile.ReadUInt16(); // …// … fileHeader.Characteristics = inFile.ReadUInt16();fileHeader.Characteristics = inFile.ReadUInt16();}}

private COFFHeader fileHeader;private COFFHeader fileHeader;

unsafe void ReadHeader(BinaryStream InFile)unsafe void ReadHeader(BinaryStream InFile){{ byte[] buffer = InFile.ReadBytes(sizeof(COFFHeader));byte[] buffer = InFile.ReadBytes(sizeof(COFFHeader));

fixed (byte* headerPtr = buffer) fixed (byte* headerPtr = buffer) {{ fileHeader = *((COFFHeader*)headerPtr);fileHeader = *((COFFHeader*)headerPtr); }}}}

Existing Binary Structures Existing Binary Structures

Page 39: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Image ProcessingImage Processing

demodemo

Page 40: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

Additional ResourcesAdditional Resources

C# Community SitesC# Community Sites http://www.gotdotnet.com/team/csharphttp://www.gotdotnet.com/team/csharp

See information page for my columnsSee information page for my columns

http://www.csharp.orghttp://www.csharp.org

C# newsgroupC# newsgroup microsoft.public.dotnet.languages.csharpmicrosoft.public.dotnet.languages.csharp

Me: [email protected]: [email protected]

Page 41: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

August 19-23, 2002August 19-23, 2002Redmond, WARedmond, WA

•5 days of training5 days of training•36 sessions, 3 tracks36 sessions, 3 tracks•Fun evening activitiesFun evening activities

www.develop.com/summercampwww.develop.com/summercamp

Page 42: DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.

© 2002 Microsoft Corporation. All rights reserved.© 2002 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.