How C++ Compilers Implement Object Orientation Eric Powders (ejp2127)
DEV300: Advanced C# Eric Gunnerson Program Manager Visual C# Microsoft Corporation.
Transcript of 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
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
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.