dev300: advanced c# eric gunnerson program manager visual c# microsoft corporation

Post on 02-Jan-2016

222 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

DEV300: Advanced C#DEV300: Advanced C#

Eric GunnersonEric GunnersonProgram ManagerProgram ManagerVisual C#Visual C#Microsoft CorporationMicrosoft 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

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

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…

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

Two Data TypesTwo Data Types

demodemo

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

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

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

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

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

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

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

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()

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

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(); }} }}}}

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); }}}}

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();}}

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); }} }}}}

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

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

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"); }}}}

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) {...}}}

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() {...}}}

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

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;}}

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

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);}}

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");

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;}}

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;}}

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);}}

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)){...}{...}

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)) {...} } } }}

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

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”

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

Image ProcessingImage Processing

demodemo

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: EricGu@Microsoft.comMe: EricGu@Microsoft.com

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

© 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.

top related