Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation."— Presentation transcript:

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

2

3 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and tricks Language tips and tricks Interoperability Interoperability Advanced C# Topics

4 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and tricks Language tips and tricks Interoperability Interoperability Advanced C# Topics

5 A Data Type Of Your Own A type that has A type that has  Operator Overloading  User-defined conversions  XML Documentation  Properties A type like Decimal… A type like Decimal…

6 Reference Or Value type? Data types all have value semantics Data types all have value semantics  val1 = val2 means copy value, not make val1 point at val2 Value type is the right choice unless Value type is the right choice unless  The type is of variable size (like string)  The type is big (> 16ish bytes) Reference types must be immutable Reference types must be immutable  Methods don’t modify value  Methods return new instance  Like string type

7 Two Data Types demo demo

8 Intro To Animation To animate a ball, we need to track: To animate a ball, we need to track:  Position (a point)  Velocity (a vector) Each frame, add velocity to position Each frame, add velocity to position Handle collisions as necessary Handle collisions as necessary

9 Collision With A Circle c v vc V 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

10 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and tricks Language tips and tricks Interoperability Interoperability Advanced C# Topics

11 Deterministic Finalization Means “you know exactly when an object is destroyed” Means “you know exactly when an object is destroyed” You want it You want it You can’t have it You can’t have it  A very complicated discussion  See http://www.gotdotnet.com/team/csharp/information http://www.gotdotnet.com/team/csharp/information  Look for article on Resource management

12 Object Destruction Two main issues: Two main issues:  Garbage collection means non- deterministic finalization  GC chooses:  When objects are destroyed  Order of destruction  Garbage collector can’t clean up unmanaged objects

13 Solution Cleanup at GC time Cleanup at GC time  Objects with unmanaged resources implement a finalizer to free those resources Early Cleanup Early Cleanup  Objects implement IDisposable, users call Dispose() to clean up

14 Scenario 1 User Calls Dispose() Unmanaged Resource Font object Dispose() Dispose() free IntPtr myResource; Font font; Dispose() means free my resources, and call Dispose() on any contained objects

15 Scenario 2 Object Finalized by GC Unmanaged Resource Font object Finalize() Dispose()? free IntPtr myResource; Font font; Finalize() means free my resources only; other managed resources will also get finalized X Finalize()

16 Implementing IDisposable Design pattern for early cleanup Design pattern for early cleanup Only required when you: Only required when you:  Wrap unmanaged resources  You’ll need a destructor too OR OR  Need to be able to clean up early Not required for the vast majority of objects Not required for the vast majority of objects

17 Destructors Object.Finalize is not accessible in C# Object.Finalize is not accessible in C# public class Resource: IDisposable { ~Resource() {...} ~Resource() {...}} public class Resource: IDisposable { protected override void Finalize() { protected override void Finalize() { try { try {...... } finally { finally { base.Finalize(); base.Finalize(); } }}

18 Doing The Implementation public 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() { Dispose(true); Dispose(true); } ~Resource() { ~Resource() { Dispose(false); Dispose(false); }}

19 Using Statement Acquire, Execute, Release pattern Acquire, Execute, Release pattern Works with any IDisposable object Works with any IDisposable object  Data access classes, streams, text readers and writers, network classes, etc. using (Resource res = new Resource()) { res.DoWork(); res.DoWork();} Resource res = new Resource(...); try { res.DoWork(); res.DoWork();} finally { if (res != null) ((IDisposable)res).Dispose(); if (res != null) ((IDisposable)res).Dispose();}

20 Using Statement 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) { 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) { 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); } }}

21 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and tricks Language tips and tricks Interoperability Interoperability Advanced C# Topics

22 Versioning What happens when base components are changed? What happens when base components are changed? Versioning an important design goal Versioning an important design goal  Virtual methods and overriding  Overload resolution  Explicit interface implementation  Const vs. readonly fields  Defaults for accessibility and virtuality

23 Versioning: Overriding class Derived: Base// version 1 { public virtual void Foo() { public virtual void Foo() { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }} class Derived: Base// version 2a { new public virtual void Foo() { new public virtual void Foo() { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }} class Derived: Base// version 2b { public override void Foo() { public override void Foo() { base.Foo(); base.Foo(); Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); }} class Base// version 1 {} class Base // version 2 { public virtual void Foo() { public virtual void Foo() { Console.WriteLine("Base.Foo"); Console.WriteLine("Base.Foo"); }}

24 Versioning: Overloading public class Base// version 1 {} public class Derived: Base// version 1 { public void Add(double x) {...} public void Add(double x) {...}} Derived d = new Derived(...); d.Add(1); public class Base// version 2 { public void Add(int x) {...} public void Add(int x) {...}}

25 Versioning: Interfaces interface IGraphics { void Draw(); void Draw(); Brush Brush { get; set; } Brush Brush { get; set; } Pen Pen { get; set; } Pen Pen { get; set; }} 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 { public void Draw() {...} public void Draw() {...}} class Bandit: IGraphics, IBandit { public void Draw() {...} // Which interface? public void Draw() {...} // Which interface?} class Bandit: IBandit, IGraphics { public void Draw() {...} public void Draw() {...} void IGraphics.Draw() {...} void IGraphics.Draw() {...}} class Bandit: IBandit, IGraphics { void IBandit.Draw() {...} void IBandit.Draw() {...} void IGraphics.Draw() {...} void IGraphics.Draw() {...}}

26 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and tricks Language tips and tricks Interoperability Interoperability Advanced C# Topics

27 Definite Assignment A variable must be definitely assigned before its value can be obtained A variable must be definitely assigned before its value can be obtained Auto-initialized vs. unassigned Auto-initialized vs. unassigned Static flow analysis looks at all possible execution paths Static flow analysis looks at all possible execution paths static int Mumble(int flags) { int n; int n; if (flags != 0){ if (flags != 0){ n = Something(); n = Something(); } return n; return n;}

28 void printf(string fmt, object[] args) { foreach (object x in args) { foreach (object x in args) {...... }} void printf(string fmt, params object[] args) { foreach (object x in args) { foreach (object x in args) {...... }} object[] args = new object[3]; args[0] = str; args[1] = int1; args[2] = int2; printf("%s %i %i", args); printf("%s %i %i", str, int1, int2); object[] args = new object[3]; args[0] = str; args[1] = int1; args[2] = int2; printf("%s %i %i", args); Parameter Arrays Methods with a variable number of parameters Methods with a variable number of parameters

29 Ref And Out Parameters Use “ref” for in/out parameter passing Use “ref” for in/out parameter passing Use “out” to return multiple values Use “out” to return multiple values Must repeat ref/out at call site Must repeat ref/out at call site static void Swap(ref int a, ref int b) {...} static void Divide(int dividend, int divisor, out int result, out int remainder) {...} out int result, out int remainder) {...} static void Main() { int x = 1, y = 2; int x = 1, y = 2; Swap(ref x, ref y); Swap(ref x, ref y);}

30 Is, As, And Typeof Operators Check if a conversion will succeed Check if a conversion will succeed Perform exception-free conversion Perform exception-free conversion Get System.Type object for a type Get System.Type object for a type if (o is string) { string s = (string)o; string s = (string)o; LogString(s); LogString(s);} string s = o as string; if (s != null) Console.WriteLine(s); if (o.GetType() == typeof(string)) Console.WriteLine("o is a string"); Console.WriteLine("o is a string");

31 Overflow Checking Integer arithmetic operations Integer arithmetic operations  C, C++, Java silently overflow checked vs. unchecked context checked vs. unchecked context  Default is unchecked, except for constants  Change with “/checked” compiler switch int i = checked(x * y); checked { int i = x * y; int i = x * y;}

32 Throw Statement Throw exception: throw e; Throw exception: throw e; Re-throw exception: throw; Re-throw exception: throw; try { DoSomething(); DoSomething();} catch (Exception e) { LogError(...); LogError(...); throw; throw;}

33 Foreach Statement Iteration of arrays Iteration of arrays Iteration of IEnumerable collections Iteration of IEnumerable collections 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) { foreach (string s in args) Console.WriteLine(s); foreach (string s in args) Console.WriteLine(s);}

34 Foreach Statement Can be modified with user-written classes Can be modified with user-written classes See my December 2001 column for more information See my December 2001 column for more information  http://www.gotdotnet.com/team/csharp/information foreach (string s in new IterReverse(names)) {...} foreach (DateTime t in new IterSort(times)) {...}

35 Lock Statement Use lock for mutual exclusion Use lock for mutual exclusion  Protect member vars from other threads Use typeof as lock for static methods Use typeof as lock for static methods class 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)) {...} }}

36 A data type of your very own A data type of your very own Deterministic finalization Deterministic finalization Versioning Versioning Language tips and trick or treat Language tips and trick or treat Interoperability Interoperability Advanced C# Topics

37 Unsafe Code When pointers are a necessity When pointers are a necessity  Advanced COM and P/Invoke interop  Existing binary structures  Performance extremes Low-level code without leaving the box Low-level code without leaving the box Basically “inline C” Basically “inline C”

38 struct COFFHeader { public ushort MachineType; public ushort MachineType; public ushort NumberOfSections; public ushort NumberOfSections; … public ushort Characteristics; public ushort Characteristics;} private COFFHeader fileHeader; 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; 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

39 Image Processing demo demo

40 Additional Resources C# Community Sites C# Community Sites  http://www.gotdotnet.com/team/csharp http://www.gotdotnet.com/team/csharp  See information page for my columns  http://www.csharp.org C# newsgroup C# newsgroup  microsoft.public.dotnet.languages.csharp Me: EricGu@Microsoft.com Me: EricGu@Microsoft.com

41 August 19-23, 2002 Redmond, WA 5 days of training5 days of training 36 sessions, 3 tracks36 sessions, 3 tracks Fun evening activitiesFun evening activities www.develop.com/summercamp

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


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

Similar presentations


Ads by Google