C# In Depth: Chapters 5 and 6
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Fri, 20 Dec 2013 21:42:17 +0000 (22:42 +0100)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Fri, 20 Dec 2013 21:42:17 +0000 (22:42 +0100)
18 files changed:
CSharpInDepth/Chapter5/Chapter5.sln [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5.userprefs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/AssemblyInfo.cs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/Chapter5.csproj [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/Main.cs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/MainWindow.cs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe [new file with mode: 0755]
CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe.mdb [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/gtk-gui/MainWindow.cs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/gtk-gui/generated.cs [new file with mode: 0644]
CSharpInDepth/Chapter5/Chapter5/gtk-gui/gui.stetic [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6.sln [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6.userprefs [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6/AssemblyInfo.cs [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6/Chapter6.csproj [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6/Main.cs [new file with mode: 0644]
CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe [new file with mode: 0755]
CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe.mdb [new file with mode: 0644]

diff --git a/CSharpInDepth/Chapter5/Chapter5.sln b/CSharpInDepth/Chapter5/Chapter5.sln
new file mode 100644 (file)
index 0000000..b6a79a4
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chapter5", "Chapter5\Chapter5.csproj", "{06326E93-0CD5-488A-A283-D26D36968815}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|x86 = Debug|x86\r
+               Release|x86 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {06326E93-0CD5-488A-A283-D26D36968815}.Debug|x86.ActiveCfg = Debug|x86\r
+               {06326E93-0CD5-488A-A283-D26D36968815}.Debug|x86.Build.0 = Debug|x86\r
+               {06326E93-0CD5-488A-A283-D26D36968815}.Release|x86.ActiveCfg = Release|x86\r
+               {06326E93-0CD5-488A-A283-D26D36968815}.Release|x86.Build.0 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(MonoDevelopProperties) = preSolution\r
+               StartupItem = Chapter5\Chapter5.csproj\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/CSharpInDepth/Chapter5/Chapter5.userprefs b/CSharpInDepth/Chapter5/Chapter5.userprefs
new file mode 100644 (file)
index 0000000..d763d61
--- /dev/null
@@ -0,0 +1,13 @@
+<Properties>
+  <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
+  <MonoDevelop.Ide.Workbench ActiveDocument="Chapter5/Main.cs">
+    <Files>
+      <File FileName="Chapter5/Main.cs" Line="157" Column="4" />
+      <File FileName="Chapter5/MainWindow.cs" Line="15" Column="3" />
+    </Files>
+  </MonoDevelop.Ide.Workbench>
+  <MonoDevelop.Ide.DebuggingService.Breakpoints>
+    <BreakpointStore />
+  </MonoDevelop.Ide.DebuggingService.Breakpoints>
+  <MonoDevelop.Ide.DebuggingService.PinnedWatches />
+</Properties>
\ No newline at end of file
diff --git a/CSharpInDepth/Chapter5/Chapter5/AssemblyInfo.cs b/CSharpInDepth/Chapter5/Chapter5/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..c378ed2
--- /dev/null
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Chapter5")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("gustavo")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/CSharpInDepth/Chapter5/Chapter5/Chapter5.csproj b/CSharpInDepth/Chapter5/Chapter5/Chapter5.csproj
new file mode 100644 (file)
index 0000000..d92dd08
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{06326E93-0CD5-488A-A283-D26D36968815}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Chapter5</RootNamespace>
+    <AssemblyName>Chapter5</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>glib-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>glade-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <SpecificVersion>False</SpecificVersion>
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="Mono.Posix" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="gtk-gui\gui.stetic">
+      <LogicalName>gui.stetic</LogicalName>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="gtk-gui\generated.cs" />
+    <Compile Include="MainWindow.cs" />
+    <Compile Include="gtk-gui\MainWindow.cs" />
+    <Compile Include="Main.cs" />
+    <Compile Include="AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/CSharpInDepth/Chapter5/Chapter5/Main.cs b/CSharpInDepth/Chapter5/Chapter5/Main.cs
new file mode 100644 (file)
index 0000000..5cf439d
--- /dev/null
@@ -0,0 +1,306 @@
+using System;
+using Gtk;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Chapter5
+{
+       class MainClass
+       {
+               delegate Stream StreamFactory();
+               delegate void SampleDelegate(string x);
+               delegate void MethodInvoker();
+
+               public static void Main (string[] args)
+               {
+                       Application.Init ();
+
+                       MainWindow win = new MainWindow ();
+
+
+                       /**
+                        * 
+                        * Listing 5.1 Subscribing to three of a button's events. 
+                        */
+                       Button buttonA = new Button ("Click me 5.1");
+                       buttonA.Pressed += new EventHandler (LogPlainEvent);
+                       buttonA.KeyPressEvent += new KeyPressEventHandler (LogKeyEvent);
+                       win.Add (buttonA);
+
+
+                       /**
+                        * 
+                        * Listing 5.2 Demonstration of method group conversion and delegate contravariance. 
+                        */
+                       Button buttonB = new Button ("Click me 5.2");
+                       buttonB.Pressed += LogPlainEvent;
+                       buttonB.KeyPressEvent += LogPlainEvent;
+                       win.Add (buttonB);
+
+
+                       /**
+                        * 
+                        * Listing 5.3 Demonstration of covariance of return types for delegates. 
+                        */
+                       StreamFactory factoryA = GenerateSampleData;
+
+                       using (Stream stream = factoryA()) {
+                               int data;
+
+                               while ((data = stream.ReadByte()) != -1) {
+                                       Console.WriteLine (data);
+                               }
+                       }
+
+
+                       /**
+                        * 
+                        * Listing 5.4 Demonstration of braking change between C# 1 and C# 2. 
+                        */
+                       Derived x = new Derived ();
+                       SampleDelegate factoryB = new SampleDelegate (x.CandidateAction);
+                       factoryB ("test");
+
+
+                       /**
+                        * 
+                        * Listing 5.5 Anonymous methods used with the Action<T> delegate type.
+                        */
+                       Action<string> printReverse = delegate(string text) {
+                               char[] chars = text.ToCharArray ();
+                               Array.Reverse (chars);
+                               Console.WriteLine (new String (chars));
+                       };
+
+                       Action<int> printRoot = delegate(int number) {
+                               Console.WriteLine (Math.Sqrt (number));
+                       };
+
+                       Action<IList<double>> printMean = delegate(IList<double> numbers) {
+                               double total = 0;
+                               foreach (double value in numbers) {
+                                       total += value;
+                               }
+                               Console.WriteLine (total / numbers.Count);
+                       };
+
+                       printReverse ("Hello Gus");
+                       printRoot (2);
+                       printMean (new double[] {1.5, 2.5, 3.5, 4.5, 5, 7, 10.1});
+
+
+                       /**
+                        * 
+                        * Listing 5.7 Returning a value from an anonymous method.
+                        */
+                       Predicate<int> isEven = delegate(int number) {
+                               return number % 2 == 0;
+                       };
+                       Console.WriteLine (isEven (1));
+                       Console.WriteLine (isEven (4));
+
+
+                       /**
+                        * 
+                        * Listing 5.8 Using anonymous methods to sort files simply.
+                        */
+                       SortAndShowFiles ("Sorted by name:", delegate(FileInfo f1, FileInfo f2) {
+                               return f1.Name.CompareTo (f2.Name);
+                       }
+                       );
+
+                       SortAndShowFiles ("Sorted by length:", delegate(FileInfo f1, FileInfo f2) {
+                               return f1.Length.CompareTo (f2.Length);
+                       }
+                       );
+
+
+                       /**
+                        * 
+                        * Listing 5.9 Subscribing to event with anonymous methods that ignore parameters.
+                        */
+                       Button buttonC = new Button ("Click me 5.9");
+                       buttonC.Pressed += delegate {
+                               Console.WriteLine ("LogPlain");
+                       };
+                       buttonC.KeyPressEvent += delegate {
+                               Console.WriteLine ("LogKey");
+                       };
+                       win.Add (buttonC);
+
+
+                       /**
+                        * 
+                        * Listing 5.10 Examples of variable kinds with respect to anonymous methods.
+                        */
+                       int outerVariable = 5;
+                       string capturedVariable = "captured";
+
+                       if (DateTime.Now.Hour == 1) {
+                               int normalLocalVariable = DateTime.Now.Minute;
+                               Console.WriteLine (normalLocalVariable);
+                       }
+
+                       MethodInvoker method = delegate() {
+                               string anonLocal = " local to anonymous method";
+                               Console.WriteLine (capturedVariable + anonLocal);
+                       };
+                       method ();
+
+
+                       /**
+                        * 
+                        * Listing 5.11 Accessing a variable both inside and outside an anonymous method.
+                        */
+                       string captured = "before methodB is created";
+
+                       MethodInvoker methodB = delegate {
+                               Console.WriteLine (captured);
+                               captured = "changed by methodB";
+                       };
+                       captured = "directly before methodB is invoked";
+                       methodB ();
+
+                       Console.WriteLine (captured);
+
+                       captured = "before second invocation";
+                       methodB ();
+
+
+                       /**
+                        * 
+                        * Listing 5.12 Demonstration of a captured variable having its lifetime extended.
+                        */
+                       MethodInvoker methodC = CreateDelegateInstance ();
+                       methodC ();
+                       methodC ();
+
+
+                       /**
+                        * 
+                        * Listing 5.13 Capturing multiple variable instantiations with multiple delegates.
+                        */
+                       List<MethodInvoker> list = new List<MethodInvoker> ();
+
+                       // The variable declared by the initial part of the loop is only instantiated once.
+                       for (int index = 0; index < 5; index++) {
+                               // Because counter is declared inside the loop, it's instantiated for each iteration.
+                               int counter = index * 10;
+                               list.Add (delegate {
+                                       Console.WriteLine (counter);
+                                       counter++;
+                               }
+                               );
+                       }
+
+                       foreach (MethodInvoker t in list) {
+                               t ();
+                       }
+                       list [0] ();
+                       list [0] ();
+                       list [0] ();
+
+                       list [1] ();
+
+
+                       /**
+                        * 
+                        * Listing 5.14 Capturing variables in different scopes. Warning: nasty code ahead!
+                        */
+                       MethodInvoker[] delegates = new MethodInvoker[2];
+
+                       int outside = 0;
+
+                       for (int i = 0; i < 2; i++) {
+                               // Because inside is declared inside the loop, it's instantiated for each iteration.
+                               int inside = 0;
+
+                               delegates[i] = delegate {
+                                       Console.WriteLine ("({0},{1})", outside, inside);
+                                       outside++;
+                                       inside++;
+                               };
+                       }
+
+                       MethodInvoker first = delegates[0];
+                       MethodInvoker second = delegates[1];
+
+                       first();
+                       first();
+                       first();
+
+                       second();
+                       second();
+
+
+
+                       win.ShowAll ();
+                       Application.Run ();
+               }
+
+
+               static void LogPlainEvent (object sender, EventArgs e)
+               {
+                       Console.WriteLine("LogPlain");
+               }
+
+
+               static void LogKeyEvent (object sender, KeyPressEventArgs e)
+               {
+                       Console.WriteLine("LogKey");
+               }
+
+
+               static MemoryStream GenerateSampleData ()
+               {
+                       byte[] buffer = new byte[16];
+                       for (int i = 0; i < buffer.Length; i++) {
+                               buffer[i] = (byte) i;
+                       }
+
+                       return new MemoryStream(buffer);
+               }
+
+
+               public void CandidateAction(string x)
+               {
+                       Console.WriteLine("Snippet.CandidateAction");
+               }
+
+
+               public class Derived:MainClass
+               {
+                       public void CandidateAction(object o)
+                       {
+                               Console.WriteLine("Derived.CandidateAction");
+                       }
+               }
+
+               static void SortAndShowFiles (string title, Comparison<FileInfo> sortOrder)
+               {
+                       FileInfo[] files = new DirectoryInfo (@"/").GetFiles ();
+
+                       Array.Sort (files, sortOrder);
+
+                       Console.WriteLine (title);
+                       foreach (FileInfo file in files) {
+                               Console.WriteLine(" {0} ({1} bytes)", file.Name, file.Length);
+                       }
+               }
+
+               static MethodInvoker CreateDelegateInstance ()
+               {
+                       int counter = 5;
+
+                       MethodInvoker ret = delegate
+                       {
+                               Console.WriteLine(counter);
+                               counter++;
+                       };
+
+                       ret();
+                       return ret;
+               }
+       }
+
+}
diff --git a/CSharpInDepth/Chapter5/Chapter5/MainWindow.cs b/CSharpInDepth/Chapter5/Chapter5/MainWindow.cs
new file mode 100644 (file)
index 0000000..b450b52
--- /dev/null
@@ -0,0 +1,16 @@
+using System;
+using Gtk;
+
+public partial class MainWindow: Gtk.Window
+{      
+       public MainWindow (): base (Gtk.WindowType.Toplevel)
+       {
+               Build ();
+       }
+       
+       protected void OnDeleteEvent (object sender, DeleteEventArgs a)
+       {
+               Application.Quit ();
+               a.RetVal = true;
+       }
+}
diff --git a/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe b/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe
new file mode 100755 (executable)
index 0000000..c5745e9
Binary files /dev/null and b/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe differ
diff --git a/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe.mdb b/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe.mdb
new file mode 100644 (file)
index 0000000..22a0c61
Binary files /dev/null and b/CSharpInDepth/Chapter5/Chapter5/bin/Debug/Chapter5.exe.mdb differ
diff --git a/CSharpInDepth/Chapter5/Chapter5/gtk-gui/MainWindow.cs b/CSharpInDepth/Chapter5/Chapter5/gtk-gui/MainWindow.cs
new file mode 100644 (file)
index 0000000..7d75d57
--- /dev/null
@@ -0,0 +1,27 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+
+public partial class MainWindow
+{
+       private global::Gtk.UIManager UIManager;
+       
+       protected virtual void Build ()
+       {
+               global::Stetic.Gui.Initialize (this);
+               // Widget MainWindow
+               this.UIManager = new global::Gtk.UIManager ();
+               global::Gtk.ActionGroup w1 = new global::Gtk.ActionGroup ("Default");
+               this.UIManager.InsertActionGroup (w1, 0);
+               this.AddAccelGroup (this.UIManager.AccelGroup);
+               this.Name = "MainWindow";
+               this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");
+               this.WindowPosition = ((global::Gtk.WindowPosition)(4));
+               if ((this.Child != null)) {
+                       this.Child.ShowAll ();
+               }
+               this.DefaultWidth = 400;
+               this.DefaultHeight = 300;
+               this.Show ();
+               this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
+       }
+}
diff --git a/CSharpInDepth/Chapter5/Chapter5/gtk-gui/generated.cs b/CSharpInDepth/Chapter5/Chapter5/gtk-gui/generated.cs
new file mode 100644 (file)
index 0000000..9636f6f
--- /dev/null
@@ -0,0 +1,29 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace Stetic
+{
+       internal class Gui
+       {
+               private static bool initialized;
+               
+               internal static void Initialize (Gtk.Widget iconRenderer)
+               {
+                       if ((Stetic.Gui.initialized == false)) {
+                               Stetic.Gui.initialized = true;
+                       }
+               }
+       }
+       
+       internal class ActionGroups
+       {
+               public static Gtk.ActionGroup GetActionGroup (System.Type type)
+               {
+                       return Stetic.ActionGroups.GetActionGroup (type.FullName);
+               }
+               
+               public static Gtk.ActionGroup GetActionGroup (string name)
+               {
+                       return null;
+               }
+       }
+}
diff --git a/CSharpInDepth/Chapter5/Chapter5/gtk-gui/gui.stetic b/CSharpInDepth/Chapter5/Chapter5/gtk-gui/gui.stetic
new file mode 100644 (file)
index 0000000..58b3a44
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<stetic-interface>
+  <configuration>
+    <images-root-path>..</images-root-path>
+    <target-gtk-version>2.12</target-gtk-version>
+  </configuration>
+  <import>
+    <widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <widget-library name="../bin/Debug/Chapter5.exe" internal="true" />
+  </import>
+  <widget class="Gtk.Window" id="MainWindow" design-size="400 300">
+    <action-group name="Default" />
+    <property name="MemberName" />
+    <property name="Title" translatable="yes">MainWindow</property>
+    <property name="WindowPosition">CenterOnParent</property>
+    <signal name="DeleteEvent" handler="OnDeleteEvent" />
+    <child>
+      <placeholder />
+    </child>
+  </widget>
+</stetic-interface>
\ No newline at end of file
diff --git a/CSharpInDepth/Chapter6/Chapter6.sln b/CSharpInDepth/Chapter6/Chapter6.sln
new file mode 100644 (file)
index 0000000..0def22a
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chapter6", "Chapter6\Chapter6.csproj", "{DD91EB8A-A3C0-4A8D-A529-82621728B868}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|x86 = Debug|x86\r
+               Release|x86 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {DD91EB8A-A3C0-4A8D-A529-82621728B868}.Debug|x86.ActiveCfg = Debug|x86\r
+               {DD91EB8A-A3C0-4A8D-A529-82621728B868}.Debug|x86.Build.0 = Debug|x86\r
+               {DD91EB8A-A3C0-4A8D-A529-82621728B868}.Release|x86.ActiveCfg = Release|x86\r
+               {DD91EB8A-A3C0-4A8D-A529-82621728B868}.Release|x86.Build.0 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(MonoDevelopProperties) = preSolution\r
+               StartupItem = Chapter6\Chapter6.csproj\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/CSharpInDepth/Chapter6/Chapter6.userprefs b/CSharpInDepth/Chapter6/Chapter6.userprefs
new file mode 100644 (file)
index 0000000..2147a1e
--- /dev/null
@@ -0,0 +1,12 @@
+<Properties>
+  <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
+  <MonoDevelop.Ide.Workbench ActiveDocument="Chapter6/Main.cs">
+    <Files>
+      <File FileName="Chapter6/Main.cs" Line="58" Column="45" />
+    </Files>
+  </MonoDevelop.Ide.Workbench>
+  <MonoDevelop.Ide.DebuggingService.Breakpoints>
+    <BreakpointStore />
+  </MonoDevelop.Ide.DebuggingService.Breakpoints>
+  <MonoDevelop.Ide.DebuggingService.PinnedWatches />
+</Properties>
\ No newline at end of file
diff --git a/CSharpInDepth/Chapter6/Chapter6/AssemblyInfo.cs b/CSharpInDepth/Chapter6/Chapter6/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..2d11b04
--- /dev/null
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Chapter6")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("gustavo")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/CSharpInDepth/Chapter6/Chapter6/Chapter6.csproj b/CSharpInDepth/Chapter6/Chapter6/Chapter6.csproj
new file mode 100644 (file)
index 0000000..4e1f340
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DD91EB8A-A3C0-4A8D-A529-82621728B868}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Chapter6</RootNamespace>
+    <AssemblyName>Chapter6</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Main.cs" />
+    <Compile Include="AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/CSharpInDepth/Chapter6/Chapter6/Main.cs b/CSharpInDepth/Chapter6/Chapter6/Main.cs
new file mode 100644 (file)
index 0000000..bbd61f5
--- /dev/null
@@ -0,0 +1,182 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Chapter6
+{
+       class MainClass
+       {
+               static readonly string Padding = new string(' ', 30);
+
+               public static void Main (string[] args)
+               {
+
+                       /**
+                        * 
+                        * Listings 6.1 and 6.2 Skeleton of th new collection type, with no iterator implementation.
+                        */
+                       object[] values = {"a", "b", "c", "d", "e"};
+                       IterationSampleBad badCollection = new IterationSampleBad(values, 3);
+                       try {
+                               foreach(object x in badCollection)
+                               {
+                                       Console.WriteLine(x);
+                               }
+                       } catch(NotImplementedException e) {
+                               Console.WriteLine("Listings 6.1 and 6.2 exception: {0}", e);
+                       }
+
+
+                       /**
+                        * 
+                        * Listings 6.3 Nested class implementing the collection's iterator.
+                        */
+                       IterationSample collection = new IterationSample(values, 3);
+                       foreach(object x in collection)
+                       {
+                               Console.WriteLine(x);
+                       }
+
+
+                       /**
+                        * 
+                        * Listings 6.4 Iterating through the sample collection with C# 2 and yield return.
+                        */
+                       IterationSampleYield yieldCollection = new IterationSampleYield(values, 3);
+                       foreach(object x in yieldCollection)
+                       {
+                               Console.WriteLine(x);
+                       }
+
+
+                       /**
+                        * 
+                        * Listings 6.5 Showing the sequence of calls between an iterator and its caller.
+                        */
+                       IEnumerable<int> iterable = CreateEnumerable();
+                       IEnumerator<int> iterator = iterable.GetEnumerator();
+                       Console.WriteLine("Starting to iterate");
+               }
+
+               static IEnumerable<int> CreateEnumerable ()
+               {
+                       Console.WriteLine ("{0}Start of CreateEnumerable()", Padding);
+
+                       for (int i=0; i < 3; i++) {
+                               Console.WriteLine("{0}About to yield {1}", Padding, i);
+                               yield return i;
+                               Console.WriteLine("{0}After yield", Padding);
+                       }
+
+                       Console.WriteLine("{0}Yielding final value", Padding);
+                       yield return -1;
+
+                       Console.WriteLine("{0}End of CreateEnumerable()", Padding);
+               }
+       }
+
+
+       public class IterationSampleBad : IEnumerable
+       {
+               object[] values;
+               int startingPoint;
+
+               public IterationSampleBad (object[] values, int startingPoint)
+               {
+                       this.values = values;
+                       this.startingPoint = startingPoint;
+               }
+
+               public IEnumerator GetEnumerator()
+               {
+                       throw new NotImplementedException();
+               }
+       }
+
+
+       // The same as the Java style of creating a custom Iterator:
+       // see http://stackoverflow.com/questions/5849154/can-we-write-our-own-iterator-in-java
+       // (basically it is the same)
+       public class IterationSample : IEnumerable
+       {
+               object[] values;
+               int startingPoint;
+
+               public IterationSample (object[] values, int startingPoint)
+               {
+                       this.values = values;
+                       this.startingPoint = startingPoint;
+               }
+
+               public IEnumerator GetEnumerator()
+               {
+                       // If GetEnumerator is called several times, serveral independent iterators should be returned.
+                       return new IterationSampleIterator(this);
+               }
+
+               // Let's create another nested class to implement the iterator itself.
+               public class IterationSampleIterator : IEnumerator
+               {
+                       IterationSample parent;
+                       // Iterators are stateful. We need to store some state somewhere (the position in this example)
+                       int position;
+
+                       internal IterationSampleIterator (IterationSample parent)
+                       {
+                               this.parent = parent;
+                               position = -1;
+                       }
+
+                       public bool MoveNext ()
+                       {
+                               if (position != parent.values.Length) {
+                                       position++;
+                               }
+                               return position < parent.values.Length;
+                       }
+
+                       public object Current {
+                               get {
+                                       if (position == -1 ||
+                                       position == parent.values.Length) {
+                                                       throw new InvalidOperationException();
+                                       }
+                                       int index = position + parent.startingPoint;
+                                       index = index % parent.values.Length;
+                                       return parent.values[index];
+                               }
+                       }
+
+                       public void Reset()
+                       {
+                               position = -1;
+                       }
+               }
+       }
+
+
+       // The C# 2.0 style! Rocks!
+       public class IterationSampleYield : IEnumerable
+       {
+               object[] values;
+               int startingPoint;
+
+               public IterationSampleYield (object[] values, int startingPoint)
+               {
+                       this.values = values;
+                       this.startingPoint = startingPoint;
+               }
+
+               public IEnumerator GetEnumerator ()
+               {
+                       // * Whenever MoveNext is called, it has to execute code from the GetEnumerator
+                       //     method until you are ready to provide the next value (in other words, until you
+                       //     hit a yield return statement)
+                       // * When the Current property is used, it has to return the last value you yielded.
+                       // * It has to know when you have finished yielding values so that MoveNext can return false.
+                       for (int index = 0; index < values.Length; index++) {
+                               yield return values[(index + startingPoint) % values.Length];
+                       }
+               }
+       }
+}
diff --git a/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe b/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe
new file mode 100755 (executable)
index 0000000..e2cf7af
Binary files /dev/null and b/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe differ
diff --git a/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe.mdb b/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe.mdb
new file mode 100644 (file)
index 0000000..03887f8
Binary files /dev/null and b/CSharpInDepth/Chapter6/Chapter6/bin/Debug/Chapter6.exe.mdb differ