├── .gitattributes ├── .gitignore ├── CLR via CS.sln ├── Ch01-1-SomeLibrary.cs ├── Ch01-1-SomeLibrary.csproj ├── Ch01-2-TypeMembersToIL.cs ├── Ch01-2-TypeMembersToIL.csproj ├── Ch02-1-SimpleProgram.cs ├── Ch02-1-SimpleProgram.csproj ├── Ch02-2-Minimum MSCorLib.cs ├── Ch02-2-Minimum MSCorLib.csproj ├── Ch02-3-AssemblyVersionInfo.cs ├── Ch02-3-BuildMultiFileLibrary.bat ├── Ch02-3-FUT.cs ├── Ch02-3-RUT.cs ├── Ch02-4-AppUsingMultiFileLibrary.cs ├── Ch02-4-AppUsingMultiFileLibrary.csproj ├── Ch03-1-AssemInfo.cs ├── Ch04-1-Type Fundamentals.cs ├── Ch04-1-Type Fundamentals.csproj ├── Ch05-1-PrimitveReferenceValueTypes.cs ├── Ch05-1-PrimitveReferenceValueTypes.csproj ├── Ch06-1-TypeMembers.cs ├── Ch06-1-TypeMembers.csproj ├── Ch07-1-LibraryDefiningConstant.cs ├── Ch07-1-LibraryDefiningConstant.csproj ├── Ch07-2-AppUsingLibraryConstant.cs ├── Ch07-2-AppUsingLibraryConstant.csproj ├── Ch07-3-LibraryDefiningReadOnlyField.cs ├── Ch07-3-LibraryDefiningReadOnlyField.csproj ├── Ch07-4-AppUsingLibraryReadOnlyField.cs ├── Ch07-4-AppUsingLibraryReadOnlyField.csproj ├── Ch07-5-Fields.cs ├── Ch07-5-Fields.csproj ├── Ch08-1-Methods.cs ├── Ch08-1-Methods.csproj ├── Ch09-1-Parameters.cs ├── Ch09-1-Parameters.csproj ├── Ch10-1-Properties.cs ├── Ch10-1-Properties.csproj ├── Ch11-1-EventSet.cs ├── Ch11-1-Events.csproj ├── Ch11-1-MailManager.cs ├── Ch11-1-TypeWithLotsOfEvents.cs ├── Ch12-1-Generics.cs ├── Ch12-1-Generics.csproj ├── Ch13-1-Interfaces.cs ├── Ch13-1-Interfaces.csproj ├── Ch14-1-CharsAndStrings.cs ├── Ch14-1-CharsAndStrings.csproj ├── Ch15-1-EnumsAndBitFlags.cs ├── Ch15-1-EnumsAndBitFlags.csproj ├── Ch16-1-Arrays.cs ├── Ch16-1-Arrays.csproj ├── Ch17-1-Delegates.cs ├── Ch17-1-Delegates.csproj ├── Ch18-1-CustomAttributes.cs ├── Ch18-1-CustomAttributes.csproj ├── Ch19-1-NullableValueTypes.cs ├── Ch19-1-NullableValueTypes.csproj ├── Ch20-1-ExceptionHandling.cs ├── Ch20-1-ExceptionHandling.csproj ├── Ch21-1-GarbageCollection.cs ├── Ch21-1-GarbageCollection.csproj ├── Ch22-1-AppDomains.cs ├── Ch22-1-AppDomains.csproj ├── Ch23-1-AssemblyLoadingAndReflection.cs ├── Ch23-1-AssemblyLoadingAndReflection.csproj ├── Ch23-2-AddIn_SDKAssembly.cs ├── Ch23-2-AddIn_SDKAssembly.csproj ├── Ch23-3-AddIn_AddInTypes.cs ├── Ch23-3-AddIn_AddInTypes.csproj ├── Ch23-4-AddIn_Host.cs ├── Ch23-4-AddIn_Host.csproj ├── Ch24-1-RuntimeSerialization.cs ├── Ch24-1-RuntimeSerialization.csproj ├── Ch25-1-WinRTComponents.cs ├── Ch25-1-WinRTComponents.csproj ├── Ch25-2-ConsumeWinRTComponents ├── Ch25-2-ConsumeWinRTComponents.jsproj ├── Ch25-2-ConsumeWinRTComponents.jsproj.user ├── PublisherCertificate.pfx ├── css │ └── default.css ├── default.html ├── images │ ├── Logo.png │ ├── SmallLogo.png │ ├── SplashScreen.png │ └── storelogo.png ├── js │ └── default.js └── package.appxmanifest ├── Ch26-1-ThreadBasics.cs ├── Ch26-1-ThreadBasics.csproj ├── Ch27-1-ComputeOps.cs ├── Ch27-1-ComputeOps.csproj ├── Ch28-1-IOOps.cs ├── Ch28-1-IOOps.csproj ├── Ch29-1-PrimitveThreadSync.cs ├── Ch29-1-PrimitveThreadSync.csproj ├── Ch30-1-HybridThreadSync.cs ├── Ch30-1-HybridThreadSync.csproj └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | 45 | # NuGet Packages 46 | *.nupkg 47 | # The packages folder can be ignored because of Package Restore 48 | **/packages/* 49 | # except build/, which is used as an MSBuild target. 50 | !**/packages/build/ 51 | # Uncomment if necessary however generally it will be regenerated when needed 52 | #!**/packages/repositories.config 53 | 54 | 55 | # Build results 56 | [Dd]ebug/ 57 | [Dd]ebugPublic/ 58 | [Rr]elease/ 59 | [Rr]eleases/ 60 | x64/ 61 | x86/ 62 | build/ 63 | bld/ 64 | [Bb]in/ 65 | [Oo]bj/ -------------------------------------------------------------------------------- /Ch01-1-SomeLibrary.cs: -------------------------------------------------------------------------------- 1 | #if !DEBUG 2 | #pragma warning disable 3002, 3005 3 | #endif 4 | using System; 5 | 6 | // Tell compiler to check for CLS compliance 7 | [assembly: CLSCompliant(true)] 8 | 9 | namespace SomeLibrary { 10 | // Warnings appear because the class is public 11 | public sealed class SomeLibraryType { 12 | 13 | // Warning: Return type of 'SomeLibrary.SomeLibraryType.Abc()' 14 | // is not CLS-compliant 15 | public UInt32 Abc() { return 0; } 16 | 17 | // Warning: Identifier 'SomeLibrary.SomeLibraryType.abc()' 18 | // differing only in case is not CLS-compliant 19 | public void abc() { } 20 | 21 | // No warning: Method is private 22 | private UInt32 ABC() { return 0; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Ch01-1-SomeLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {03634A5F-09FF-47D5-8BAF-3430B87561D8} 9 | Library 10 | Properties 11 | SomeLibrary 12 | Ch01-1-SomeLibrary 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | 38 | 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /Ch01-2-TypeMembersToIL.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 660, 661, 67 2 | 3 | using System; 4 | 5 | internal sealed class Test { 6 | // Constructor 7 | public Test() { } 8 | 9 | // Finalizer 10 | ~Test() { } 11 | 12 | // Operator overload 13 | public static Boolean operator ==(Test t1, Test t2) { 14 | return true; 15 | } 16 | public static Boolean operator !=(Test t1, Test t2) { 17 | return false; 18 | } 19 | 20 | // An operator overload 21 | public static Test operator +(Test t1, Test t2) { return null; } 22 | 23 | // A property 24 | public String AProperty { 25 | get { return null; } 26 | set { } 27 | } 28 | 29 | // An indexer 30 | public String this[Int32 x] { 31 | get { return null; } 32 | set { } 33 | } 34 | 35 | // An event 36 | #pragma warning disable 67 37 | public event EventHandler AnEvent; 38 | #pragma warning restore 67 39 | } 40 | -------------------------------------------------------------------------------- /Ch01-2-TypeMembersToIL.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {124DDBD4-517F-4BCE-B043-AA1D8800EB80} 9 | Library 10 | Properties 11 | TypeMembersToIL 12 | Ch01-2-TypeMembersToIL 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /Ch02-1-SimpleProgram.cs: -------------------------------------------------------------------------------- 1 | public sealed class Program { 2 | public static void Main() { 3 | System.Console.WriteLine("Hi"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Ch02-1-SimpleProgram.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {CE20198E-6095-4BFC-B351-D2426081E687} 9 | Exe 10 | Properties 11 | SimpleProgram 12 | Ch02-1-SimpleProgram 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | x86 33 | false 34 | 35 | 36 | pdbonly 37 | true 38 | bin\Release\ 39 | TRACE 40 | prompt 41 | 4 42 | AllRules.ruleset 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /Ch02-2-Minimum MSCorLib.cs: -------------------------------------------------------------------------------- 1 | // This project is a DLL that has the "Do not reference mscorlib.dll" option turned on 2 | 3 | namespace System { 4 | public class Object { } 5 | public struct Byte { } 6 | public struct SByte { } 7 | public struct Int16 { } 8 | public struct Int32 { } 9 | public struct Int64 { } 10 | public struct UInt16 { } 11 | public struct UInt32 { } 12 | public struct UInt64 { } 13 | public struct IntPtr { } 14 | public struct UIntPtr { } 15 | public struct Single { } 16 | public struct Double { } 17 | public struct Char { } 18 | public struct Boolean { } 19 | public class Type { } 20 | public class ValueType { } 21 | public class Enum { } 22 | public struct Void { } 23 | public class Array { } 24 | public class Exception { } 25 | public class ParamArrayAttribute { } 26 | public struct RuntimeTypeHandle { } 27 | public struct RuntimeFieldHandle { } 28 | public class Attribute { } 29 | public class Delegate { } 30 | public class MulticastDelegate { } 31 | public class String { } 32 | public interface IDisposable { } 33 | public enum AttributeTargets { Assembly = 1, Class = 4, } 34 | 35 | [AttributeUsage(AttributeTargets.Class, Inherited = true)] 36 | public sealed class AttributeUsageAttribute : Attribute { 37 | public AttributeUsageAttribute(AttributeTargets validOn) { } 38 | public bool AllowMultiple { get; set; } 39 | public bool Inherited { get; set; } 40 | } 41 | } 42 | 43 | namespace System.Runtime.InteropServices { 44 | public class OutAttribute { } 45 | } 46 | 47 | namespace System.Runtime.Versioning { 48 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] 49 | public sealed class TargetFrameworkAttribute : Attribute { 50 | public TargetFrameworkAttribute(String frameworkName) { } 51 | public String FrameworkDisplayName { get; set; } 52 | } 53 | } 54 | 55 | namespace System.Reflection { 56 | public class DefaultMemberAttribute { } 57 | } 58 | 59 | namespace System.Collections { 60 | public interface IEnumerable { } 61 | public interface IEnumerator { } 62 | } 63 | -------------------------------------------------------------------------------- /Ch02-2-Minimum MSCorLib.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {8FABA5DA-DF09-4A97-86B1-EEF2DB24D36E} 9 | Library 10 | Properties 11 | MinimumMSCorLib 12 | Ch02-2-MinimumMSCorLib 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | true 29 | AnyCPU 30 | false 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | true 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /Ch02-3-AssemblyVersionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // FileDescription version information: 4 | [assembly: AssemblyTitle("MultiFileLibrary.dll")] 5 | 6 | // Comments version information: 7 | [assembly: AssemblyDescription("This assembly contains MultiFileLibrary's types")] 8 | 9 | // CompanyName version information: 10 | [assembly: AssemblyCompany("Wintellect")] 11 | 12 | // ProductName version information: 13 | [assembly: AssemblyProduct("Wintellect (R) MultiFileLibrary's Type Library")] 14 | 15 | // LegalCopyright version information: 16 | [assembly: AssemblyCopyright("Copyright (c) Wintellect 2013")] 17 | 18 | // LegalTrademarks version information: 19 | [assembly:AssemblyTrademark("MultiFileLibrary is a registered trademark of Wintellect")] 20 | 21 | // AssemblyVersion version information: 22 | [assembly: AssemblyVersion("3.0.0.0")] 23 | 24 | // FILEVERSION/FileVersion version information: 25 | [assembly: AssemblyFileVersion("1.0.0.0")] 26 | 27 | // PRODUCTVERSION/ProductVersion version information: 28 | [assembly: AssemblyInformationalVersion("2.0.0.0")] 29 | 30 | // Set the Language field (discussed later in the "Culture" section) 31 | [assembly:AssemblyCulture("")] 32 | -------------------------------------------------------------------------------- /Ch02-3-BuildMultiFileLibrary.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | Rem %1="$(DevEnvDir)", %2="$(SolutionDir)", %3="$(OutDir)" 3 | 4 | rem Set all the VS environment variables 5 | pushd %1 6 | call ..\Tools\VSVars32.bat 7 | popd 8 | 9 | rem Change to the solution directory 10 | cd %2 11 | 12 | REM There are two ways to build this multi-file assembly 13 | REM The line below picks one of those ways 14 | Goto Way1 15 | 16 | :Way1 17 | csc /t:module /debug:full /out:Ch02-3-RUT.netmodule Ch02-3-RUT.cs 18 | csc /t:library /debug:full /out:Ch02-3-MultiFileLibrary.dll /addmodule:Ch02-3-RUT.netmodule Ch02-3-FUT.cs Ch02-3-AssemblyVersionInfo.cs 19 | md %3 20 | move /Y Ch02-3-RUT.netmodule %3 21 | move /Y Ch02-3-RUT.pdb %3 22 | move /Y Ch02-3-MultiFileLibrary.dll %3 23 | move /Y Ch02-3-MultiFileLibrary.pdb %3 24 | goto Exit 25 | 26 | :Way2 27 | csc /t:module /debug:full /out:Ch02-3-RUT.netmodule Ch02-3-RUT.cs 28 | csc /t:module /debug:full /out:Ch02-3-FUT.netmodule Ch02-3-FUT.cs Ch02-3-AssemblyVersionInfo.cs 29 | al /out:Ch02-3-MultiFileLibrary.dll /t:library Ch02-3-RUT.netmodule Ch02-3-FUT.netmodule 30 | md %3 31 | move /Y Ch02-3-RUT.netmodule %3 32 | move /Y Ch02-3-RUT.pdb %3 33 | move /Y Ch02-3-FUT.netmodule %3 34 | move /Y Ch02-3-FUT.pdb %3 35 | move /Y Ch02-3-MultiFileLibrary.dll %3 36 | move /Y Ch02-3-MultiFileLibrary.pdb %3 37 | goto Exit 38 | 39 | :Exit 40 | 41 | -------------------------------------------------------------------------------- /Ch02-3-FUT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public sealed class AFrequentlyUsedType { 4 | public AFrequentlyUsedType() { 5 | Console.WriteLine("A frequently used type was constructed."); 6 | } 7 | } -------------------------------------------------------------------------------- /Ch02-3-RUT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public sealed class ARarelyUsedType { 4 | public ARarelyUsedType() { 5 | Console.WriteLine("A rarely used type was constructed."); 6 | } 7 | } -------------------------------------------------------------------------------- /Ch02-4-AppUsingMultiFileLibrary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class AppUsingMultiFileLibrary { 4 | public static void Main() { 5 | new AFrequentlyUsedType(); 6 | new ARarelyUsedType(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Ch02-4-AppUsingMultiFileLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {90E62D22-181E-4028-9EC1-54E890CA8018} 9 | Exe 10 | Properties 11 | AppUsingMultifileLibrary 12 | Ch02-4-AppUsingMultifileLibrary 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | false 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | false 29 | false 30 | false 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | false 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | False 51 | bin\Debug\Ch02-3-MultiFileLibrary.dll 52 | 53 | 54 | 55 | 56 | "$(SolutionDir)Ch02-3-BuildMultiFileLibrary.bat" "$(DevEnvDir)" "$(SolutionDir)" "$(OutDir)" 57 | 58 | 65 | -------------------------------------------------------------------------------- /Ch03-1-AssemInfo.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Module: AssemInfo.cs 3 | Notices: Copyright (c) 2013 Jeffrey Richter 4 | ******************************************************************************/ 5 | 6 | 7 | using System.Reflection; 8 | 9 | 10 | /////////////////////////////////////////////////////////////////////////////// 11 | 12 | 13 | // Set the version CompanyName, LegalCopyright and LegalTrademarks fields 14 | [assembly:AssemblyCompany("The Jeffrey Richter Company")] 15 | [assembly:AssemblyCopyright("Copyright (c) 2013 Jeffrey Richter")] 16 | [assembly:AssemblyTrademark( 17 | "JeffTypes is a registered trademark of the Richter Company")] 18 | 19 | 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | // Set the version ProductName and ProductVersion fields 24 | [assembly:AssemblyProduct("Jeffrey Richter Type Library")] 25 | [assembly:AssemblyInformationalVersion("2.0.0.0")] 26 | 27 | 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | // Set the version FileVersion, AssemblyVersion, 32 | // FileDescription, and Comments fields. 33 | [assembly:AssemblyFileVersion("1.0.0.0")] 34 | [assembly:AssemblyVersion("3.0.0.0")] 35 | [assembly:AssemblyTitle("Jeff's type assembly")] 36 | [assembly:AssemblyDescription("This assembly contains Jeff's types")] 37 | 38 | 39 | /////////////////////////////////////////////////////////////////////////////// 40 | 41 | 42 | // Set the assembly's culture (""=neutral). 43 | [assembly:AssemblyCulture("")] 44 | 45 | 46 | /////////////////////////////////////////////////////////////////////////////// 47 | 48 | 49 | #if !StronglyNamedAssembly 50 | 51 | // Weakly named assemblies are never signed 52 | [assembly:AssemblyDelaySign(false)] 53 | 54 | #else 55 | 56 | // Strongly named assemblies are usually delay signed while building and 57 | // completely signed using SN.exe's -R or -Rc switch. 58 | [assembly:AssemblyDelaySign(true)] 59 | 60 | #if !SignedUsingACryptoServiceProvider 61 | 62 | // Give the name of the file that contains the public/private key pair. 63 | // If delay signing, only the public key is used. 64 | [assembly:AssemblyKeyFile("MyCompany.keys")] 65 | 66 | // Note: If AssemblyKeyFile and AssemblyKeyName are both specified, 67 | // here's what happens... 68 | // 1) If the container exists, the key file is ignored. 69 | // 2) If the container doesn't exist, the keys from the key 70 | // file are copied into the container and the assembly is signed. 71 | 72 | #else 73 | 74 | // Give the name of the cryptographic service provider (CSP) container 75 | // that contains the public/private key pair. 76 | // If delay signing, only the public key is used. 77 | [assembly:AssemblyKeyName("")] 78 | 79 | #endif 80 | 81 | #endif 82 | 83 | 84 | //////////////////////////////// End of File ////////////////////////////////// 85 | -------------------------------------------------------------------------------- /Ch04-1-Type Fundamentals.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch04-1-Type Fundamentals.cs -------------------------------------------------------------------------------- /Ch04-1-Type Fundamentals.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {F6E2F875-FA2A-4263-BAC7-103BDD2DBFD0} 9 | Exe 10 | Properties 11 | TypeFundamentals 12 | Ch04-1-TypeFundamentals 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /Ch05-1-PrimitveReferenceValueTypes.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch05-1-PrimitveReferenceValueTypes.cs -------------------------------------------------------------------------------- /Ch05-1-PrimitveReferenceValueTypes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {8A705576-BC44-461E-995C-5A296DC93CEB} 9 | Exe 10 | Properties 11 | PrimitiveReferenceValueTypes 12 | Ch05-1-PrimitiveReferenceValueTypes 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | False 53 | ..\..\..\..\..\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Microsoft.CSharp.dll 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /Ch06-1-TypeMembers.cs: -------------------------------------------------------------------------------- 1 | // Only one of the following 4 symbol be uncomment at any one time 2 | #define V1 3 | //#define V2a 4 | //#define V2b 5 | //#define V2c 6 | 7 | #if !DEBUG 8 | #pragma warning disable 414, 67 9 | #endif 10 | using System; 11 | 12 | public sealed class SomeType { // 1 13 | // Nested class 14 | private class SomeNestedType { } // 2 15 | 16 | // Constant, read-only, and static read/write field 17 | private const Int32 c_SomeConstant = 1; // 3 18 | private readonly String m_SomeReadOnlyField = "2"; // 4 19 | private static Int32 s_SomeReadWriteField = 3; // 5 20 | 21 | // Type constructor 22 | static SomeType() { } // 6 23 | 24 | // Instance constructors 25 | public SomeType() { } // 7 26 | public SomeType(Int32 x) { } // 8 27 | 28 | 29 | // Static and instance methods 30 | public static void Main() { } // 9 31 | 32 | public String InstanceMethod() { return null; } // 10 33 | 34 | // Instance property 35 | public Int32 SomeProp { // 11 36 | get { return 0; } // 12 37 | set { } // 13 38 | } 39 | 40 | // Instance parameterful property (indexer) 41 | public Int32 this[String s] { // 14 42 | get { return 0; } // 15 43 | set { } // 16 44 | } 45 | 46 | // Instance event 47 | public event EventHandler SomeEvent; // 17 48 | } 49 | 50 | internal static class OverridingAccessibility { 51 | class Base { 52 | protected virtual void M() { } 53 | } 54 | 55 | class Derived1 : Base { 56 | protected override void M() { } 57 | } 58 | 59 | class Derived2 : Base { 60 | protected override void M() { } 61 | public static void Main() { } 62 | } 63 | } 64 | 65 | internal static class DifferentCalls { 66 | public static void Go() { 67 | Console.WriteLine(); // Call a static method 68 | 69 | Object o = new Object(); 70 | o.GetHashCode(); // Call a virtual instance method 71 | o.GetType(); // Call a nonvirtual instance method 72 | } 73 | } 74 | 75 | #region Versioning Components With Virtual Methods 76 | public sealed class VersioningComponentsWithVirtualMethods { 77 | public static void Main() { 78 | CompanyB.BetterPhone phone = new CompanyB.BetterPhone(); 79 | phone.Dial(); 80 | } 81 | } 82 | 83 | 84 | /////////////////////////////////////////////////////////////////////// 85 | 86 | 87 | #if V1 88 | namespace CompanyA { 89 | public class Phone { 90 | public void Dial() { 91 | Console.WriteLine("Phone.Dial"); 92 | // Do work to dial the phone here. 93 | } 94 | } 95 | } 96 | 97 | 98 | namespace CompanyB { 99 | public class BetterPhone : CompanyA.Phone { 100 | 101 | // This Dial method has nothing to do with Phone's Dial method 102 | new public void Dial() { 103 | Console.WriteLine("BetterPhone.Dial"); 104 | EstablishConnection(); 105 | base.Dial(); 106 | } 107 | 108 | protected virtual void EstablishConnection() { 109 | Console.WriteLine("BetterPhone.EstablishConnection"); 110 | // Do work to establish the connection. 111 | } 112 | } 113 | } 114 | #endif 115 | 116 | 117 | /////////////////////////////////////////////////////////////////////// 118 | 119 | 120 | #if V2a || V2b || V2c 121 | namespace CompanyA { 122 | public class Phone { 123 | public void Dial() { 124 | Console.WriteLine("Phone.Dial"); 125 | EstablishConnection(); 126 | // Do work to dial the phone here. 127 | } 128 | 129 | protected virtual void EstablishConnection() { 130 | Console.WriteLine("Phone.EstablishConnection"); 131 | // Do work to establish the connection. 132 | } 133 | } 134 | } 135 | #endif 136 | 137 | 138 | /////////////////////////////////////////////////////////////////////// 139 | 140 | 141 | #if V2a 142 | namespace CompanyB { 143 | public class BetterPhone : CompanyA.Phone { 144 | 145 | // Keep 'new' to mark this method as having no 146 | // relationship to the base type's Dial method. 147 | new public void Dial() { 148 | Console.WriteLine("BetterPhone.Dial"); 149 | EstablishConnection(); 150 | base.Dial(); 151 | } 152 | 153 | // Add 'new' to mark this method as having no 154 | // relationship to the base type's EstablishConnection method. 155 | new protected virtual void EstablishConnection() { 156 | Console.WriteLine("BetterPhone.EstablishConnection"); 157 | // Do work to establish the connection. 158 | } 159 | } 160 | } 161 | #endif 162 | 163 | 164 | #if V2b 165 | namespace CompanyB { 166 | public class BetterPhone : CompanyA.Phone { 167 | // Delete our Dial method (inherit Dial from base) 168 | 169 | // Remove 'new' and change 'virtual' to 'override' to 170 | // mark this method as having a relationship to the base 171 | protected override void EstablishConnection() { 172 | Console.WriteLine("BetterPhone.EstablishConnection"); 173 | // Do work to establish the connection. 174 | } 175 | } 176 | } 177 | #endif 178 | 179 | 180 | #if V2c 181 | namespace CompanyB { 182 | public class BetterPhone : CompanyA.Phone { 183 | 184 | // Keep 'new' to mark this method as having no 185 | // relationship to the base type's Dial method. 186 | new public void Dial() { 187 | Console.WriteLine("BetterPhone.Dial"); 188 | EstablishConnection(); 189 | base.Dial(); 190 | } 191 | 192 | // Remove 'new' and change 'virtual' to 'override' to 193 | // mark this method as having a relationship to the base 194 | protected override void EstablishConnection() { 195 | Console.WriteLine("BetterPhone.EstablishConnection"); 196 | // Do work to establish the connection. 197 | } 198 | } 199 | } 200 | #endif 201 | #endregion -------------------------------------------------------------------------------- /Ch06-1-TypeMembers.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {A6983BC1-0D5A-487A-AE8E-C33F3FE79853} 9 | Library 10 | Properties 11 | TypeMembers 12 | Ch06-1-TypeMembers 13 | false 14 | 15 | 16 | 3.5 17 | 18 | 19 | v4.5 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | true 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | 414,067 32 | true 33 | AllRules.ruleset 34 | false 35 | 36 | 37 | pdbonly 38 | true 39 | bin\Release\ 40 | TRACE 41 | prompt 42 | 4 43 | AllRules.ruleset 44 | false 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Ch07-1-LibraryDefiningConstant.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch07-1-LibraryDefiningConstant.cs -------------------------------------------------------------------------------- /Ch07-1-LibraryDefiningConstant.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {2E28E8B5-620F-465A-9D8F-D9FAE8AF97F4} 9 | Library 10 | Properties 11 | LibraryDefiningConstant 12 | Ch07-1-LibraryDefiningConstant 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Ch07-2-AppUsingLibraryConstant.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public sealed class Program { 4 | static void Main() { 5 | Console.WriteLine("Max entries supported in list: " 6 | + SomeLibraryType.MaxEntriesInList); 7 | } 8 | } -------------------------------------------------------------------------------- /Ch07-2-AppUsingLibraryConstant.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {F76BDAF3-6A76-415D-B3BB-CD14E7AE1AFD} 9 | Exe 10 | Properties 11 | AppUsingLibraryConstant 12 | Ch07-2-AppUsingLibraryConstant 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | {2E28E8B5-620F-465A-9D8F-D9FAE8AF97F4} 49 | Ch07-1-LibraryDefiningConstant 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Ch07-3-LibraryDefiningReadOnlyField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public sealed class SomeLibraryType { 4 | // The static is required to associate the field with the type. 5 | public static readonly Int32 MaxEntriesInList = 50; 6 | } -------------------------------------------------------------------------------- /Ch07-3-LibraryDefiningReadOnlyField.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {1B6DDBC3-B59F-4150-9720-A6C1705ECF11} 9 | Library 10 | Properties 11 | LibraryDefiningReadOnlyField 12 | Ch07-3-LibraryDefiningReadOnlyField 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Ch07-4-AppUsingLibraryReadOnlyField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public sealed class Program { 4 | static void Main() { 5 | Console.WriteLine("Max entries supported in list: " 6 | + SomeLibraryType.MaxEntriesInList); 7 | } 8 | } -------------------------------------------------------------------------------- /Ch07-4-AppUsingLibraryReadOnlyField.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {0E9D85EC-4CD2-49B1-BBF0-DED41BB419A9} 9 | Exe 10 | Properties 11 | AppUsingLibraryReadOnlyField 12 | Ch07-4-AppUsingLibraryReadOnlyField 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | {1B6DDBC3-B59F-4150-9720-A6C1705ECF11} 49 | Ch07-3-LibraryDefiningReadOnlyField 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Ch07-5-Fields.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 169 2 | 3 | using System; 4 | 5 | public sealed class SomeType { 6 | // This is a static read-only field; its value is calculated and 7 | // stored in memory when this class is initialized at run time. 8 | public static readonly Random s_random = new Random(); 9 | 10 | // This is a static read/write field. 11 | private static Int32 s_numberOfWrites = 0; 12 | 13 | // This is an instance read-only field. 14 | public readonly String Pathname = "Untitled"; 15 | 16 | // This is an instance read/write field. 17 | private System.IO.FileStream m_fs; 18 | 19 | public SomeType(String pathname) { 20 | // This line changes a read-only field. 21 | // This is OK because the code is in a constructor. 22 | this.Pathname = pathname; 23 | } 24 | 25 | public String DoSomething() { 26 | // This line reads and writes to the static read/write field. 27 | s_numberOfWrites = s_numberOfWrites + 1; 28 | 29 | // This line reads the read-only instance field. 30 | return Pathname; 31 | } 32 | } 33 | 34 | internal static class ReadOnlyReferences { 35 | public sealed class AType { 36 | // InvalidChars must always refer to the same array object 37 | public static readonly Char[] InvalidChars = new Char[] { 'A', 'B', 'C' }; 38 | } 39 | 40 | public sealed class AnotherType { 41 | public static void M() { 42 | // The lines below are legal, compile, and successfully 43 | // change the characters in the InvalidChars array 44 | AType.InvalidChars[0] = 'X'; 45 | AType.InvalidChars[1] = 'Y'; 46 | AType.InvalidChars[2] = 'Z'; 47 | 48 | // The line below is illegal and will not compile because 49 | // what InvalidChars refers to cannot be changed 50 | //AType.InvalidChars = new Char[] { 'X', 'Y', 'Z' }; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Ch07-5-Fields.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {6A10F850-1EB0-4E6D-AA7C-4A15A79DF5BA} 9 | Library 10 | Properties 11 | Fields 12 | Ch07-5-Fields 13 | 14 | 15 | 16 | 17 | 3.5 18 | 19 | 20 | v4.5 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | AllRules.ruleset 33 | false 34 | 35 | 36 | pdbonly 37 | true 38 | bin\Release\ 39 | TRACE 40 | prompt 41 | 4 42 | AllRules.ruleset 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Ch08-1-Methods.cs: -------------------------------------------------------------------------------- 1 | #if !DEBUG 2 | #pragma warning disable 414, 169 3 | #endif 4 | using System; 5 | using System.Diagnostics; 6 | using System.Text; 7 | using System.Collections.Generic; 8 | 9 | namespace Example1 { 10 | internal sealed class SomeType { 11 | private Int32 m_x = 5; 12 | } 13 | } 14 | 15 | 16 | namespace Example2 { 17 | #pragma warning disable 169 18 | internal sealed class SomeType { 19 | private Int32 m_x = 5; 20 | private String m_s = "Hi there"; 21 | private Double m_d = 3.14159; 22 | private Byte m_b; 23 | 24 | // Here are some constructors. 25 | public SomeType() { /* ... */ } 26 | public SomeType(Int32 x) { /* ... */ } 27 | public SomeType(String s) { /* ...; */ m_d = 10; } 28 | } 29 | #pragma warning restore 169 30 | } 31 | 32 | 33 | namespace Example3 { 34 | internal sealed class SomeType { 35 | // Do not explicitly initialize the fields here 36 | private Int32 m_x; 37 | private String m_s; 38 | private Double m_d; 39 | private Byte m_b; 40 | 41 | // This method MUST be called by all constructors. 42 | private void SetFieldDefaults() { 43 | m_x = 5; 44 | m_s = "Hi there"; 45 | m_d = 3.14159; 46 | m_b = 0xff; 47 | } 48 | 49 | // This constructor sets all fields to their default. 50 | public SomeType() { 51 | SetFieldDefaults(); 52 | } 53 | 54 | // This constructor sets all fields to their default, then changes m_x. 55 | public SomeType(Int32 x) { 56 | SetFieldDefaults(); 57 | m_x = x; 58 | } 59 | 60 | // This constructor sets all fields to their default, then changes m_s. 61 | public SomeType(String s) { 62 | SetFieldDefaults(); 63 | m_s = s; 64 | } 65 | 66 | // This constructor sets all fields to their default, then changes m_x & m_s. 67 | public SomeType(Int32 x, String s) { 68 | SetFieldDefaults(); 69 | m_x = x; 70 | m_s = s; 71 | } 72 | } 73 | } 74 | 75 | 76 | 77 | internal struct SomeValType { 78 | static SomeValType() { 79 | Console.WriteLine("This never gets displayed"); 80 | } 81 | public Int32 m_x; 82 | } 83 | 84 | public sealed class Program { 85 | public static void Main() { 86 | SomeValType[] a = new SomeValType[10]; 87 | a[0].m_x = 123; 88 | Console.WriteLine(a[0].m_x); // Displays 123 89 | 90 | new FieldInitializationInCtor("Test"); 91 | TypeConstructorPerformance.Go(); 92 | ConversionOperator.Go(); 93 | ExtensionMethods.Go(); 94 | } 95 | } 96 | 97 | internal sealed class FieldInitializationInCtor { 98 | // No code here to explicitly initialize the fields 99 | private Int32 x; 100 | private String s; 101 | private Double d; 102 | private Byte b; 103 | 104 | // This constructor must be called by all the other constructors. 105 | // This constructor contains the code to initialize the fields. 106 | public FieldInitializationInCtor() { 107 | x = 5; 108 | s = "Hi There!"; 109 | d = 3.14159; 110 | } 111 | 112 | // This constructor calls the default constructor first. 113 | public FieldInitializationInCtor(Int32 x) 114 | : this() { 115 | this.x = x; 116 | } 117 | 118 | // This constructor calls the default constructor first. 119 | public FieldInitializationInCtor(String s) 120 | : this() { 121 | this.s = s; 122 | } 123 | } 124 | 125 | 126 | public sealed class TypeConstructorPerformance { 127 | public static void Go() { 128 | const Int32 iterations = 1000 * 1000 * 1000; 129 | PerfTest1(iterations); 130 | PerfTest2(iterations); 131 | } 132 | 133 | // Since this class doesn't explicitly define a type constructor, 134 | // C# marks the type definition with BeforeFieldInit in the metadata. 135 | internal sealed class BeforeFieldInit { 136 | public static Int32 s_x = 123; 137 | } 138 | 139 | // Since this class does explicitly define a type constructor, 140 | // C# doesn't mark the type definition with BeforeFieldInit in the metadata. 141 | internal sealed class Precise { 142 | public static Int32 s_x; 143 | static Precise() { s_x = 123; } 144 | } 145 | 146 | // When this method is JIT compiled, the type constructors for 147 | // the BeforeFieldInit and Precise classes HAVE NOT executed yet 148 | // and therefore, calls to these constructors are embedded in 149 | // this method's code making it run slower 150 | private static void PerfTest1(Int32 iterations) { 151 | Stopwatch sw = Stopwatch.StartNew(); 152 | for (Int32 x = 0; x < iterations; x++) { 153 | // The JIT compiler hoists the code to call BeforeFieldInit's 154 | // type constructor so that it executes before the loop starts 155 | BeforeFieldInit.s_x = 1; 156 | } 157 | Console.WriteLine("PerfTest1: {0} BeforeFieldInit", sw.Elapsed); 158 | 159 | sw = Stopwatch.StartNew(); 160 | for (Int32 x = 0; x < iterations; x++) { 161 | // The JIT compiler emits the code to call Precise's 162 | // type constructor here so that it checks whether it 163 | // has to call the constructor with each loop iteration 164 | Precise.s_x = 1; 165 | } 166 | Console.WriteLine("PerfTest1: {0} Precise", sw.Elapsed); 167 | } 168 | 169 | // When this method is JIT compiled, the type constructors for 170 | // the BeforeFieldInit and Precise classes HAVE executed 171 | // and therefore, calls to these constructors are NOT embedded 172 | // in this method's code making it run faster 173 | private static void PerfTest2(Int32 iterations) { 174 | Stopwatch sw = Stopwatch.StartNew(); 175 | for (Int32 x = 0; x < iterations; x++) { 176 | BeforeFieldInit.s_x = 1; 177 | } 178 | Console.WriteLine("PerfTest2: {0} BeforeFieldInit", sw.Elapsed); 179 | 180 | sw = Stopwatch.StartNew(); 181 | for (Int32 x = 0; x < iterations; x++) { 182 | Precise.s_x = 1; 183 | } 184 | Console.WriteLine("PerfTest2: {0} Precise", sw.Elapsed); 185 | } 186 | } 187 | 188 | internal sealed class ConversionOperator { 189 | public static void Go() { 190 | Rational r1 = 5; // Implicit cast from Int32 to Rational 191 | Rational r2 = 2.5f; // Implicit cast from Single to Rational 192 | 193 | Int32 x = (Int32)r1; // Explicit cast from Rational to Int32 194 | Single s = (Single)r2; // Explicit cast from Rational to Single 195 | } 196 | 197 | public sealed class Rational { 198 | // Constructs a Rational from an Int32 199 | public Rational(Int32 num) { /* ... */ } 200 | 201 | // Constructs a Rational from a Single 202 | public Rational(Single num) { /* ... */ } 203 | 204 | // Convert a Rational to an Int32 205 | public Int32 ToInt32() { /* ... */ return 0; } 206 | 207 | // Convert a Rational to a Single 208 | public Single ToSingle() { /* ... */ return 0f; } 209 | 210 | // Implicitly constructs and returns a Rational from an Int32 211 | public static implicit operator Rational(Int32 num) { 212 | return new Rational(num); 213 | } 214 | 215 | // Implicitly constructs and returns a Rational from a Single 216 | public static implicit operator Rational(Single num) { 217 | return new Rational(num); 218 | } 219 | 220 | // Explicitly returns an Int32 from a Rational 221 | public static explicit operator Int32(Rational r) { 222 | return r.ToInt32(); 223 | } 224 | 225 | // Explicitly returns a Single from a Rational 226 | public static explicit operator Single(Rational r) { 227 | return r.ToSingle(); 228 | } 229 | } 230 | } 231 | 232 | #region Extension Method Demo 233 | internal static class StringBuilderExtensions { 234 | public static Int32 IndexOf(this StringBuilder sb, Char value) { 235 | for (Int32 index = 0; index < sb.Length; index++) 236 | if (sb[index] == value) return index; 237 | return -1; 238 | } 239 | } 240 | 241 | 242 | internal static class ExtensionMethods { 243 | public static void Go() { 244 | { 245 | var sb = new StringBuilder("Hello. My name is Jeff."); // The initial string 246 | 247 | // Change period to exclamation mark and get # characters in 1st sentence (5). 248 | Int32 index = StringBuilderExtensions.IndexOf(sb.Replace('.', '!'), '!'); 249 | 250 | sb.Replace('.', '!'); // Change period to exclamation mark 251 | index = StringBuilderExtensions.IndexOf(sb, '!'); // Get # characters in 1st sentence (5) 252 | 253 | // Change period to exclamation mark and get # characters in 1st sentence (5). 254 | index = sb.Replace('.', '!').IndexOf('!'); 255 | } 256 | 257 | { 258 | // sb is null 259 | StringBuilder sb = null; 260 | 261 | // Calling extension method: NullReferenceException will NOT be thrown when calling IndexOf 262 | // NullReferenceException will be thrown inside IndexOf’s for loop 263 | sb.IndexOf('X'); 264 | 265 | // Calling instance method: NullReferenceException WILL be thrown when calling Replace 266 | sb.Replace('.', '!'); 267 | } 268 | SomeMethod(); 269 | } 270 | 271 | public static void SomeMethod() { 272 | // Shows each Char on a separate line in the console 273 | "Grant".ShowItems(); 274 | 275 | // Shows each String on a separate line in the console 276 | new[] { "Jeff", "Kristin" }.ShowItems(); 277 | 278 | // Shows each Int32 value on a separate line in the console 279 | new List() { 1, 2, 3 }.ShowItems(); 280 | 281 | // Create an Action delegate that refers to the static ShowItems extension method 282 | // and has the first argument initialized to reference the “Jeff” string. 283 | Action a = "Jeff".ShowItems; 284 | // Invoke the delegate which calls ShowItems passing it a reference to the “Jeff” string. 285 | a(); 286 | } 287 | 288 | private static void ShowItems(this IEnumerable collection) { 289 | foreach (var item in collection) 290 | Console.WriteLine(item); 291 | Console.WriteLine(); 292 | } 293 | } 294 | #endregion 295 | 296 | internal static class PartialMethodsDemo { 297 | private static class Inheritance { 298 | // Tool-produced code in some source code file: 299 | internal class Base { 300 | private String m_name; 301 | 302 | // Called before changing the m_name field 303 | protected virtual void OnNameChanging(String value) { 304 | } 305 | 306 | public String Name { 307 | get { return m_name; } 308 | set { 309 | OnNameChanging(value.ToUpper()); // Inform class of potential change 310 | m_name = value; // Change the field 311 | } 312 | } 313 | } 314 | 315 | 316 | // Developer-produced code is some other source code file: 317 | internal class Derived : Base { 318 | protected override void OnNameChanging(string value) { 319 | if (String.IsNullOrEmpty(value)) 320 | throw new ArgumentNullException("value"); 321 | } 322 | } 323 | } 324 | internal static class PartialMethods { 325 | // Tool-produced code in some source code file: 326 | internal sealed partial class Base { 327 | private String m_name; 328 | 329 | // This defining-partial-method-declaration is called before changing the m_name field 330 | partial void OnNameChanging(String value); 331 | 332 | public String Name { 333 | get { return m_name; } 334 | set { 335 | OnNameChanging(value.ToUpper()); // Inform class of potential change 336 | m_name = value; // Change the field 337 | } 338 | } 339 | } 340 | 341 | // Developer-produced code is some other source code file: 342 | internal sealed partial class Base { 343 | 344 | #if false // Make 'true' to test the code with this method existing 345 | // This implementing-partial-method-declaration is called before m_name is changed 346 | partial void OnNameChanging(String value) { 347 | if (String.IsNullOrEmpty(value)) 348 | throw new ArgumentNullException("value"); 349 | } 350 | #endif 351 | } 352 | } 353 | 354 | public static void Go() { 355 | var inheritance = new Inheritance.Derived(); 356 | inheritance.Name = "Jeff"; 357 | 358 | var partialMethods = new PartialMethods.Base(); 359 | partialMethods.Name = "Jeff"; 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /Ch08-1-Methods.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {D9D7A4D1-AFD3-4448-B7B1-291AA3FA6F1D} 9 | Exe 10 | Properties 11 | Methods 12 | Ch08-1-Methods 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | 414 31 | AllRules.ruleset 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Ch09-1-Parameters.cs: -------------------------------------------------------------------------------- 1 | #define V1 2 | //#define V2 3 | //#define V3 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | public static class Parameters { 9 | public static void Main() { 10 | OptionalAndNamedParameters.Go(); 11 | MethodsThatTakeVariableArguments.Go(); 12 | } 13 | } 14 | 15 | internal static class OptionalAndNamedParameters { 16 | private static Int32 s_n = 0; 17 | 18 | public static void Go() { 19 | ImplicitlyTypedLocalVariables(); 20 | 21 | // 1. Same as: M(9, "A", default(DateTime), new Guid()); 22 | M(); 23 | 24 | // 2. Same as: M(8, "X", default(DateTime), new Guid()); 25 | M(8, "X"); 26 | 27 | // 3. Same as: M(5, "A", DateTime.Now, Guid.NewGuid()); 28 | M(5, guid: Guid.NewGuid(), dt: DateTime.Now); 29 | 30 | // 4. Same as: M(0, "1", default(DateTime), new Guid()); 31 | M(s_n++, s_n++.ToString()); 32 | 33 | // 5. Same as: String t1 = "2"; Int32 t2 = 3; 34 | // M(t2, t1, default(DateTime), new Guid()); 35 | M(s: (s_n++).ToString(), x: s_n++); 36 | } 37 | 38 | private static void M(Int32 x = 9, String s = "A", 39 | DateTime dt = default(DateTime), Guid guid = new Guid()) { 40 | 41 | Console.WriteLine("x={0}, s={1}, dt={2}, guid={3}", x, s, dt, guid); 42 | } 43 | 44 | private static void ImplicitlyTypedLocalVariables() { 45 | var name = "Jeff"; 46 | ShowVariableType(name); // Displays: System.String 47 | 48 | // var n = null; // Error 49 | var x = (Exception)null; // OK, but not much value 50 | ShowVariableType(x); // Displays: System.Exception 51 | 52 | var numbers = new Int32[] { 1, 2, 3, 4 }; 53 | ShowVariableType(numbers); // Displays: System.Int32[] 54 | 55 | // Less typing for complex types 56 | var collection = new Dictionary() { { ".NET", 4.0f } }; 57 | 58 | // Displays: System.Collections.Generic.Dictionary`2[System.String,System.Single] 59 | ShowVariableType(collection); 60 | 61 | foreach (var item in collection) { 62 | // Displays: System.Collections.Generic.KeyValuePair`2[System.String,System.Single] 63 | ShowVariableType(item); 64 | } 65 | } 66 | 67 | private static void ShowVariableType(T t) { Console.WriteLine(typeof(T)); } 68 | } 69 | 70 | 71 | internal static class OutAndRefParameters { 72 | #if V1 73 | public static void Go() { 74 | Int32 x; // x is uninitialized 75 | SetVal(out x); // x doesn’t have to be initialized. 76 | Console.WriteLine(x); // Displays "10" 77 | } 78 | 79 | private static void SetVal(out Int32 v) { 80 | v = 10; // This method must initialize v. 81 | } 82 | #endif 83 | #if V2 84 | public static void Main() { 85 | Int32 x = 5; // x is initialized 86 | AddVal(ref x); // x must be initialized. 87 | Console.WriteLine(x); // Displays "15" 88 | } 89 | 90 | private static void AddVal(ref Int32 v) { 91 | v += 10; // This method can use the initialized value in v. 92 | } 93 | #endif 94 | #if V3 95 | public static void Main() { 96 | Int32 x; // x is not initialized. 97 | 98 | // The following line fails to compile, producing 99 | // error CS0165: Use of unassigned local variable 'x'. 100 | AddVal(ref x); 101 | 102 | Console.WriteLine(x); 103 | } 104 | 105 | private static void AddVal(ref Int32 v) { 106 | v += 10; // This method can use the initialized value in v. 107 | } 108 | #endif 109 | 110 | public static void Swap(ref Object a, ref Object b) { 111 | Object t = b; 112 | b = a; 113 | a = t; 114 | } 115 | 116 | #if true 117 | public static void SomeMethod() { 118 | String s1 = "Jeffrey"; 119 | String s2 = "Richter"; 120 | Swap(ref s1, ref s2); 121 | Console.WriteLine(s1); // Displays "Richter" 122 | Console.WriteLine(s2); // Displays "Jeffrey" 123 | } 124 | #endif 125 | 126 | public static void SomeMethod2() { 127 | String s1 = "Jeffrey"; 128 | String s2 = "Richter"; 129 | 130 | // Variables that are passed by reference 131 | // must match what the method expects. 132 | Object o1 = s1, o2 = s2; 133 | Swap(ref o1, ref o2); 134 | 135 | // Now cast the objects back to strings. 136 | s1 = (String)o1; 137 | s2 = (String)o2; 138 | 139 | Console.WriteLine(s1); // Displays "Richter" 140 | Console.WriteLine(s2); // Displays "Jeffrey" 141 | } 142 | 143 | public static void Swap(ref T a, ref T b) { 144 | T t = b; 145 | b = a; 146 | a = t; 147 | } 148 | } 149 | 150 | internal static class MethodsThatTakeVariableArguments { 151 | public static void Go() { 152 | // Displays "15" 153 | Console.WriteLine(Add(new Int32[] { 1, 2, 3, 4, 5 })); 154 | 155 | // Displays "15" 156 | Console.WriteLine(Add(1, 2, 3, 4, 5)); 157 | 158 | // Displays "0" 159 | Console.WriteLine(Add()); 160 | 161 | DisplayTypes(new Object(), new Random(), "Jeff", 5); 162 | } 163 | 164 | private static Int32 Add(params Int32[] values) { 165 | // NOTE: it is possible to pass the 'values' 166 | // array to other methods if you want to. 167 | 168 | Int32 sum = 0; 169 | for (Int32 x = 0; x < values.Length; x++) 170 | sum += values[x]; 171 | return sum; 172 | } 173 | 174 | 175 | private static void DisplayTypes(params Object[] objects) { 176 | foreach (Object o in objects) 177 | Console.WriteLine(o.GetType()); 178 | } 179 | } 180 | 181 | /////////////////////////////////////////////////////////////////////////////// 182 | 183 | public sealed class Point { 184 | static void Add(Point p) { /* ... */ } 185 | static void Add(ref Point p) { /* ... */ } 186 | 187 | // 'Add' cannot define overloaded methods that differ only on ref and out 188 | // static void Add(out Point p) { /* ... */ } 189 | } 190 | 191 | ////////////////////////////// End of File //////////////////////////////////// 192 | -------------------------------------------------------------------------------- /Ch09-1-Parameters.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {9B2DE75B-6430-4549-BD33-7A7DABCC8556} 9 | Exe 10 | Properties 11 | Parameters 12 | Ch09-1-Parameters 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 52 | -------------------------------------------------------------------------------- /Ch10-1-Properties.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch10-1-Properties.cs -------------------------------------------------------------------------------- /Ch10-1-Properties.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {7FD131AD-4A04-4127-99D2-50E5835D6DE5} 9 | Exe 10 | Properties 11 | Properties 12 | Ch10-1-Properties 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Ch11-1-EventSet.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch11-1-EventSet.cs -------------------------------------------------------------------------------- /Ch11-1-Events.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {4A8F9C1D-B97B-420D-8436-5CA641A0FB2C} 9 | Exe 10 | Properties 11 | Events 12 | Ch11-1-Events 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Ch11-1-MailManager.cs: -------------------------------------------------------------------------------- 1 | //#define CompilerImplementedEventMethods 2 | using System; 3 | using System.Threading; 4 | 5 | public static class Events { 6 | public static void Main() { 7 | MailManager.Go(); 8 | TypeWithLotsOfEventsTest(); 9 | } 10 | 11 | private static void TypeWithLotsOfEventsTest() { 12 | // The code here tests the event 13 | TypeWithLotsOfEvents twle = new TypeWithLotsOfEvents(); 14 | 15 | // Add a callback here 16 | twle.Foo += HandleFooEvent; 17 | twle.SimulateFoo(); 18 | Console.WriteLine("The callback was invoked 1 time above" + Environment.NewLine); 19 | 20 | // Add another callback here 21 | twle.Foo += HandleFooEvent; 22 | twle.SimulateFoo(); 23 | Console.WriteLine("The callback was invoked 2 times above" + Environment.NewLine); 24 | 25 | // Remove a callback here 26 | twle.Foo -= HandleFooEvent; 27 | twle.SimulateFoo(); 28 | Console.WriteLine("The callback was invoked 1 time above" + Environment.NewLine); 29 | 30 | // Remove another callback here 31 | twle.Foo -= HandleFooEvent; 32 | twle.SimulateFoo(); 33 | Console.WriteLine("The callback was invoked 0 times above" + Environment.NewLine); 34 | 35 | Console.WriteLine("Press to terminate this application."); 36 | Console.ReadLine(); 37 | } 38 | 39 | private static void HandleFooEvent(object sender, FooEventArgs e) { 40 | Console.WriteLine("Handling Foo Event here..."); 41 | } 42 | } 43 | 44 | /////////////////////////////////////////////////////////////////////////////// 45 | 46 | // Step #1: Define a type that will hold any additional information that 47 | // should be sent to receivers of the event notification 48 | internal sealed class NewMailEventArgs : EventArgs { 49 | 50 | private readonly String m_from, m_to, m_subject; 51 | 52 | public NewMailEventArgs(String from, String to, String subject) { 53 | m_from = from; m_to = to; m_subject = subject; 54 | } 55 | 56 | public String From { get { return m_from; } } 57 | public String To { get { return m_to; } } 58 | public String Subject { get { return m_subject; } } 59 | } 60 | 61 | internal class MailManager { 62 | public static void Go() { 63 | // Construct a MailManager object 64 | MailManager mm = new MailManager(); 65 | 66 | // Construct a Fax object passing it the MailManager object 67 | Fax fax = new Fax(mm); 68 | 69 | // Construct a Pager object passing it the MailManager object 70 | Pager pager = new Pager(mm); 71 | 72 | // Simulate an incoming mail message 73 | mm.SimulateNewMail("Jeffrey", "Kristin", "I Love You!"); 74 | 75 | // Force the Fax object to unregister itself with the MailManager 76 | fax.Unregister(mm); 77 | 78 | // Simulate an incoming mail message 79 | mm.SimulateNewMail("Jeffrey", "Mom & Dad", "Happy Birthday."); 80 | } 81 | 82 | #if CompilerImplementedEventMethods 83 | // Step #2: Define the event member 84 | public event EventHandler NewMail; 85 | #else 86 | // Add private field which refers to the head of the delegate linked-list 87 | private EventHandler m_NewMail; 88 | 89 | // Add an event member to the class 90 | public event EventHandler NewMail { 91 | // Explicitly implement the 'add' method 92 | add { 93 | // Without thread-safety, add a handler 94 | // (passed as 'value') to the delegate linked list 95 | m_NewMail += value; 96 | } 97 | 98 | // Explicitly implement the 'remove' method 99 | remove { 100 | // Without thread-safety, remove a handler 101 | // (passed as 'value') from the delegate linked list 102 | m_NewMail -= value; 103 | } 104 | } 105 | 106 | #endif 107 | 108 | // Step #3: Define a method responsible for raising the event 109 | // to notify registered objects that the event has occurred 110 | // If this class is sealed, make this method private and nonvirtual 111 | protected virtual void OnNewMail(NewMailEventArgs e) { 112 | // Copy a reference to the delegate field now into a temporary field for thread safety 113 | //e.Raise(this, ref m_NewMail); 114 | 115 | #if CompilerImplementedEventMethods 116 | EventHandler temp = Volatile.Read(ref NewMail); 117 | #else 118 | EventHandler temp = Volatile.Read(ref m_NewMail); 119 | #endif 120 | 121 | // If any methods registered interest with our event, notify them 122 | if (temp != null) temp(this, e); 123 | } 124 | 125 | // Step #4: Define a method that translates the 126 | // input into the desired event 127 | public void SimulateNewMail(String from, String to, String subject) { 128 | 129 | // Construct an object to hold the information we wish 130 | // to pass to the receivers of our notification 131 | NewMailEventArgs e = new NewMailEventArgs(from, to, subject); 132 | 133 | // Call our virtual method notifying our object that the event 134 | // occurred. If no type overrides this method, our object will 135 | // notify all the objects that registered interest in the event 136 | OnNewMail(e); 137 | } 138 | } 139 | 140 | public static class EventArgExtensions { 141 | public static void Raise(this TEventArgs e, Object sender, ref EventHandler eventDelegate) { 142 | // Copy a reference to the delegate field now into a temporary field for thread safety 143 | EventHandler temp = Volatile.Read(ref eventDelegate); 144 | 145 | // If any methods registered interest with our event, notify them 146 | if (temp != null) temp(sender, e); 147 | } 148 | } 149 | 150 | internal sealed class Fax { 151 | // Pass the MailManager object to the constructor 152 | public Fax(MailManager mm) { 153 | // Construct an instance of the EventHandler 154 | // delegate that refers to our FaxMsg callback method. 155 | // Register our callback with MailManager's NewMail event 156 | mm.NewMail += FaxMsg; 157 | } 158 | 159 | // This is the method the MailManager will call 160 | // when a new e-mail message arrives 161 | private void FaxMsg(Object sender, NewMailEventArgs e) { 162 | // 'sender' identifies the MailManager object in case 163 | // we want to communicate back to it. 164 | 165 | // 'e' identifies the additional event information 166 | // the MailManager wants to give us. 167 | 168 | // Normally, the code here would fax the e-mail message. 169 | // This test implementation displays the info in the console 170 | Console.WriteLine("Faxing mail message:"); 171 | Console.WriteLine(" From={0}, To={1}, Subject={2}", 172 | e.From, e.To, e.Subject); 173 | } 174 | 175 | // This method could be executed to have the Fax object unregister itself with the NewMail 176 | // event so that it no longer receives notifications 177 | public void Unregister(MailManager mm) { 178 | // Unregister ourself with MailManager's NewMail event 179 | mm.NewMail -= FaxMsg; 180 | } 181 | } 182 | 183 | /////////////////////////////////////////////////////////////////////////////// 184 | 185 | internal sealed class Pager { 186 | // Pass the MailManager object to the constructor 187 | public Pager(MailManager mm) { 188 | // Construct an instance of the ProcessMailMsgEventHandler 189 | // delegate that refers to our SendMsgToPager callback method. 190 | // Register our callback with MailManager's ProcessMailMsg event 191 | mm.NewMail += SendMsgToPager; 192 | } 193 | 194 | // This is the method that the MailManager will call 195 | // when a new e-mail message arrives 196 | private void SendMsgToPager(Object sender, NewMailEventArgs e) { 197 | // 'sender' identifies the MailManager in case we want to communicate back to it. 198 | // 'e' identifies the additional event information that the MailManager wants to give us. 199 | 200 | // Normally, the code here would send the e-mail message to a pager. 201 | // This test implementation displays the info on the console 202 | Console.WriteLine("Sending mail message to pager:"); 203 | Console.WriteLine(" From={0}, To={1}, Subject={2}", e.From, e.To, e.Subject); 204 | } 205 | 206 | public void Unregister(MailManager mm) { 207 | // Unregister ourself with MailManager's ProcessMailMsg event 208 | mm.NewMail -= SendMsgToPager; 209 | } 210 | } 211 | 212 | //////////////////////////////// End of File ////////////////////////////////// 213 | -------------------------------------------------------------------------------- /Ch11-1-TypeWithLotsOfEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch11-1-TypeWithLotsOfEvents.cs -------------------------------------------------------------------------------- /Ch12-1-Generics.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch12-1-Generics.cs -------------------------------------------------------------------------------- /Ch12-1-Generics.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {09882A1C-87D3-4844-9EC9-A6CA8B961199} 9 | Exe 10 | Properties 11 | Generics 12 | Ch12-1-Generics 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /Ch13-1-Interfaces.cs: -------------------------------------------------------------------------------- 1 | #define EIMITypeSafety_Version3 2 | #define EIMINoBaseCall_Version2 3 | #if !DEBUG 4 | #pragma warning disable 219 5 | #endif 6 | 7 | using System; 8 | 9 | public static class Interfaces { 10 | public static void Main() { 11 | ImplementingAnInterface.Go(); 12 | InterfaceReimplementation.Go(); 13 | ExplicitInterfaceMethodImpl.Go(); 14 | GenericsAndInterfaces.Go(); 15 | UsingEIMI.Go(); 16 | EIMITypeSafety.Go(); 17 | EIMINoBaseCall.Go(); 18 | } 19 | } 20 | 21 | internal static class ImplementingAnInterface { 22 | public static void Go() { 23 | Point[] points = new Point[] { 24 | new Point(3, 3), 25 | new Point(1, 2), 26 | }; 27 | 28 | if (points[0].CompareTo(points[1]) > 0) { 29 | Point tempPoint = points[0]; 30 | points[0] = points[1]; 31 | points[1] = tempPoint; 32 | } 33 | Console.WriteLine("Points from closest to (0, 0) to farthest:"); 34 | foreach (Point p in points) 35 | Console.WriteLine(p); 36 | } 37 | 38 | // Point is derived from System.Object and implements IComparable. 39 | public sealed class Point : IComparable { 40 | private Int32 m_x, m_y; 41 | 42 | public Point(Int32 x, Int32 y) { 43 | m_x = x; 44 | m_y = y; 45 | } 46 | 47 | // This method implements IComparable for Point 48 | public Int32 CompareTo(Point other) { 49 | return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y) 50 | - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y)); 51 | } 52 | 53 | public override String ToString() { 54 | return String.Format("({0}, {1})", m_x, m_y); 55 | } 56 | } 57 | } 58 | 59 | internal static class InterfaceReimplementation { 60 | public static void Go() { 61 | /************************* First Example *************************/ 62 | Base b = new Base(); 63 | 64 | // Call's Dispose by using b's type: "Base's Dispose" 65 | b.Dispose(); 66 | 67 | // Call's Dispose by using b's object's type: "Base's Dispose" 68 | ((IDisposable)b).Dispose(); 69 | 70 | 71 | /************************* Second Example ************************/ 72 | Derived d = new Derived(); 73 | 74 | // Call's Dispose by using d's type: "Derived's Dispose" 75 | d.Dispose(); 76 | 77 | // Call's Dispose by using d's object's type: "Derived's Dispose" 78 | ((IDisposable)d).Dispose(); 79 | 80 | 81 | /************************* Third Example *************************/ 82 | b = new Derived(); 83 | 84 | // Call's Dispose by using b's type: "Base's Dispose" 85 | b.Dispose(); 86 | 87 | // Call's Dispose by using b's object's type: "Derived's Dispose" 88 | ((IDisposable)b).Dispose(); 89 | } 90 | 91 | // This class is derived from Object and it implements IDisposable 92 | internal class Base : IDisposable { 93 | // This method is implicitly sealed and cannot be overridden 94 | public void Dispose() { 95 | Console.WriteLine("Base's Dispose"); 96 | } 97 | } 98 | 99 | // This class is derived from Base and it re-implements IDisposable 100 | internal class Derived : Base, IDisposable { 101 | // This method cannot override Base's Dispose. 'new' is used to indicate 102 | // that this method re-implements IDisposable's Dispose method 103 | new public void Dispose() { 104 | Console.WriteLine("Derived's Dispose"); 105 | 106 | // NOTE: The next line shows how to call a base class's implementation (if desired) 107 | // base.Dispose(); 108 | } 109 | } 110 | } 111 | 112 | internal static class ExplicitInterfaceMethodImpl { 113 | public static void Go() { 114 | SimpleType st = new SimpleType(); 115 | 116 | // This calls the public Dispose method implementation 117 | st.Dispose(); 118 | 119 | // This calls IDisposable's Dispose method implementation 120 | IDisposable d = st; 121 | d.Dispose(); 122 | } 123 | 124 | public sealed class SimpleType : IDisposable { 125 | #if false 126 | public void Dispose() { Console.WriteLine("Dispose"); } 127 | #else 128 | public void Dispose() { Console.WriteLine("public Dispose"); } 129 | void IDisposable.Dispose() { Console.WriteLine("IDisposable Dispose"); } 130 | #endif 131 | } 132 | } 133 | 134 | internal static class GenericsAndInterfaces { 135 | public static void Go() { 136 | Number n = new Number(); 137 | 138 | // Here, I compare the value in n with an Int32 (5) 139 | IComparable cInt32 = n; 140 | Int32 result = cInt32.CompareTo(5); 141 | 142 | // Here, I compare the value in n with a String ("5") 143 | IComparable cString = n; 144 | result = cString.CompareTo("5"); 145 | } 146 | 147 | // This class implements the generic IComparable interface twice 148 | public sealed class Number : IComparable, IComparable { 149 | private Int32 m_val = 5; 150 | 151 | // This method implements IComparable’s CompareTo 152 | public Int32 CompareTo(Int32 n) { 153 | return m_val.CompareTo(n); 154 | } 155 | 156 | // This method implements IComparable’s CompareTo 157 | public Int32 CompareTo(String s) { 158 | return m_val.CompareTo(Int32.Parse(s)); 159 | } 160 | } 161 | 162 | private static void SomeMethod1() { 163 | Int32 x = 1, y = 2; 164 | IComparable c = x; 165 | 166 | // CompareTo expects an Object; passing y (an Int32) is OK 167 | c.CompareTo(y); // Boxing occurs here 168 | 169 | // CompareTo expects an Object; passing "2" (a String) compiles 170 | // but an ArgumentException is thrown at runtime 171 | c.CompareTo("2"); 172 | } 173 | 174 | private static void SomeMethod2() { 175 | Int32 x = 1, y = 2; 176 | IComparable c = x; 177 | 178 | // CompareTo expects an Int32; passing y (an Int32) is OK 179 | c.CompareTo(y); // Boxing occurs here 180 | 181 | // CompareTo expects an Int32; passing "2" (a String) results 182 | // in a compiler error indicating that String cannot be cast to an Int32 183 | // c.CompareTo("2"); 184 | } 185 | 186 | public sealed class SomeType { 187 | private static void Test() { 188 | Int32 x = 5; 189 | 190 | // This call to M compiles fine because 191 | // Int32 implements IComparable AND IConvertible 192 | M(x); 193 | 194 | // This call to M causes a compiler error because 195 | // Guid implements IComparable but it does not implement IConvertible 196 | // Guid g = new Guid(); 197 | // M(g); 198 | } 199 | 200 | // M’s type parameter, T, is constrained to work only with types that 201 | // implement both the IComparable AND IConvertible interfaces 202 | private static Int32 M(T t) where T : IComparable, IConvertible { 203 | // ... 204 | return 0; 205 | } 206 | } 207 | } 208 | 209 | internal static class UsingEIMI { 210 | public static void Go() { 211 | MarioPizzeria mp = new MarioPizzeria(); 212 | 213 | // This line calls MarioPizzeria’s public GetMenu method 214 | mp.GetMenu(); 215 | 216 | // These lines call MarioPizzeria’s IWindow.GetMenu method 217 | IWindow window = mp; 218 | window.GetMenu(); 219 | 220 | // These lines call MarioPizzeria’s IRestaurant.GetMenu method 221 | IRestaurant restaurant = mp; 222 | restaurant.GetMenu(); 223 | } 224 | 225 | public interface IWindow { 226 | Object GetMenu(); 227 | } 228 | 229 | public interface IRestaurant { 230 | Object GetMenu(); 231 | } 232 | 233 | // This type is derived from System.Object and 234 | // implements the IWindow and IRestaurant interfaces. 235 | public class MarioPizzeria : IWindow, IRestaurant { 236 | 237 | // This is the implementation for IWindow’s GetMenu method. 238 | Object IWindow.GetMenu() { 239 | // ... 240 | return null; 241 | } 242 | 243 | // This is the implementation for IRestaurant’s GetMenu method. 244 | Object IRestaurant.GetMenu() { 245 | // ... 246 | return null; 247 | } 248 | 249 | // This (optional method) is a GetMenu method that has nothing 250 | // to do with an interface. 251 | public Object GetMenu() { 252 | // ... 253 | return null; 254 | } 255 | } 256 | } 257 | 258 | public static class EIMITypeSafety { 259 | internal struct SomeValueType : IComparable { 260 | private Int32 m_x; 261 | public SomeValueType(Int32 x) { m_x = x; } 262 | 263 | #if EIMITypeSafety_Version1 264 | public Int32 CompareTo(Object other) { 265 | return (m_x - ((SomeValueType)other).m_x); 266 | } 267 | #else 268 | public Int32 CompareTo(SomeValueType other) { 269 | return (m_x - other.m_x); 270 | } 271 | 272 | // NOTE: No public/private used on the next line 273 | Int32 IComparable.CompareTo(Object other) { 274 | return CompareTo((SomeValueType)other); 275 | } 276 | #endif 277 | } 278 | 279 | public static void Go() { 280 | #if EIMITypeSafety_Version1 281 | SomeValueType v = new SomeValueType(0); 282 | Object o = new Object(); 283 | Int32 n = v.CompareTo(v); // Undesired boxing 284 | n = v.CompareTo(o); // InvalidCastException 285 | #endif 286 | 287 | #if EIMITypeSafety_Version2 288 | SomeValueType v = new SomeValueType(0); 289 | Object o = new Object(); 290 | Int32 n = v.CompareTo(v); // No boxing 291 | n = v.CompareTo(o); // compile-time error 292 | #endif 293 | 294 | #if EIMITypeSafety_Version3 295 | SomeValueType v = new SomeValueType(0); 296 | IComparable c = v; // Boxing! 297 | 298 | Object o = new Object(); 299 | Int32 n = c.CompareTo(v); // Undesired boxing 300 | n = c.CompareTo(o); // InvalidCastException 301 | #endif 302 | } 303 | } 304 | 305 | internal static class EIMINoBaseCall { 306 | #if EIMINoBaseCall_Version1 307 | internal class Base : IComparable { 308 | // Explicit Interface Method Implementation 309 | Int32 IComparable.CompareTo(Object o) { 310 | Console.WriteLine("Base's CompareTo"); 311 | return 0; 312 | } 313 | } 314 | 315 | internal class Derived : Base, IComparable { 316 | // A public method that is also the interface implementation 317 | public Int32 CompareTo(Object o) { 318 | Console.WriteLine("Derived's CompareTo"); 319 | 320 | // This attempt to call the base class's EIMI causes a compiler error: 321 | // error CS0117: 'Base' does not contain a definition for 'CompareTo' 322 | base.CompareTo(o); 323 | return 0; 324 | } 325 | } 326 | #endif 327 | 328 | #if EIMINoBaseCall_Version2 329 | internal class Base : IComparable { 330 | 331 | // Explicit Interface Method Implementation 332 | Int32 IComparable.CompareTo(Object o) { 333 | Console.WriteLine("Base's IComparable CompareTo"); 334 | return CompareTo(o); // This now calls the virtual method 335 | } 336 | 337 | // Virtual method for derived classes (this method could have any name) 338 | public virtual Int32 CompareTo(Object o) { 339 | Console.WriteLine("Base's virtual CompareTo"); 340 | return 0; 341 | } 342 | } 343 | 344 | internal class Derived : Base, IComparable { 345 | 346 | // A public method that is also the interface implementation 347 | public override Int32 CompareTo(Object o) { 348 | Console.WriteLine("Derived's CompareTo"); 349 | 350 | // Now, we can call Base's virtual method 351 | base.CompareTo(o); 352 | return 0; 353 | } 354 | } 355 | #endif 356 | 357 | public static void Go() { 358 | Derived d = new Derived(); 359 | d.CompareTo(null); 360 | } 361 | } -------------------------------------------------------------------------------- /Ch13-1-Interfaces.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {1CB88E45-6870-4854-9BDD-2A03799775B4} 9 | Exe 10 | Properties 11 | Interfaces 12 | Ch13-1-Interfaces 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Ch14-1-CharsAndStrings.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch14-1-CharsAndStrings.cs -------------------------------------------------------------------------------- /Ch14-1-CharsAndStrings.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {9F1DEF08-0BF2-4D91-8DB5-658CC1297DA2} 9 | Exe 10 | Properties 11 | CharsAndStrings 12 | Ch14-1-CharsAndStrings 13 | Program 14 | 15 | 16 | 3.5 17 | 18 | 19 | v4.5 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | AllRules.ruleset 32 | true 33 | false 34 | 35 | 36 | pdbonly 37 | true 38 | bin\Release\ 39 | TRACE 40 | prompt 41 | 4 42 | AllRules.ruleset 43 | true 44 | true 45 | false 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Ch15-1-EnumsAndBitFlags.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch15-1-EnumsAndBitFlags.cs -------------------------------------------------------------------------------- /Ch15-1-EnumsAndBitFlags.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {AB348A06-F9EC-4B50-A96E-7D3DD6D907BB} 9 | Exe 10 | Properties 11 | EnumsAndBitFlags 12 | Ch15-1-EnumsAndBitFlags 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /Ch16-1-Arrays.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Module: Arrays.cs 3 | Notices: Copyright (c) 2013 Jeffrey Richter 4 | ******************************************************************************/ 5 | 6 | using System; 7 | using System.Diagnostics; 8 | using System.IO; 9 | 10 | /////////////////////////////////////////////////////////////////////////////// 11 | 12 | 13 | public static class Program { 14 | public static void Main() { 15 | ArrayIntro(); 16 | ArrayDemo(); 17 | ArrayCasting(); 18 | DynamicArrays.Go(); 19 | ArrayTypes.Go(); 20 | MultiDimArrayPerformance.Go(); 21 | StackallocAndInlineArrays.Go(); 22 | } 23 | 24 | private static void ArrayIntro() { 25 | String[] sa = new String[1]; 26 | Array a1 = Array.CreateInstance(typeof(String), new Int32[] { 1 }, new Int32[] { 0 }); 27 | Array a2 = Array.CreateInstance(typeof(String), new Int32[] { 1 }, new Int32[] { 1 }); 28 | Console.WriteLine(sa.GetType().ToString()); 29 | Console.WriteLine(a1.GetType().ToString()); 30 | Console.WriteLine(a2.GetType().ToString()); 31 | } 32 | 33 | private static void ArrayRankInfo(String name, Array a) { 34 | Console.WriteLine("Number of dimensions in \"{0}\" array (of type {1}): ", 35 | name, a.GetType().ToString(), a.Rank); 36 | for (int r = 0; r < a.Rank; r++) { 37 | Console.WriteLine("Rank: {0}, LowerBound = {1}, UpperBound = {2}", 38 | r, a.GetLowerBound(r), a.GetUpperBound(r)); 39 | } 40 | Console.WriteLine(); 41 | } 42 | 43 | private static void ArrayDemo() { 44 | Int32[] arrayOfInt32s = new Int32[10]; 45 | ArrayRankInfo("arrayOfInt32s", arrayOfInt32s); 46 | 47 | String[,] matrixOfStrings = new String[10, 20]; 48 | ArrayRankInfo("matrixOfStrings", matrixOfStrings); 49 | 50 | // Create an array of 3 Int32s: lower bound= -2, upper bound = 0 51 | Array arrayOfObjects = Array.CreateInstance(typeof(Object), new Int32[] { 3 }, new Int32[] { -2 }); 52 | ArrayRankInfo("arrayOfObjects", arrayOfObjects); 53 | 54 | arrayOfObjects.SetValue(10, -2); 55 | arrayOfObjects.SetValue(20, -1); 56 | arrayOfObjects.SetValue(30, +0); 57 | Console.WriteLine("Array elements: a[-2] = {0}, a[-1] = {1}, a[0] = {2}", 58 | arrayOfObjects.GetValue(-2), arrayOfObjects.GetValue(-1), arrayOfObjects.GetValue(0)); 59 | } 60 | 61 | private static void ArrayCasting() { 62 | // Create a 2-dim FileStream array 63 | FileStream[,] fs2dim = new FileStream[5, 10]; 64 | 65 | // Implicit cast to a 2-dim Object array 66 | Object[,] o2dim = fs2dim; 67 | 68 | // Can't cast from 2-dim array to 1-dim array 69 | // Compiler error CS0030: Cannot convert type 'object[*,*]' to 'System.IO.Stream[]' 70 | //Stream[] s1dim = (Stream[]) o2dim; 71 | 72 | // Explicit cast to 2-dim Stream array 73 | Stream[,] s2dim = (Stream[,])o2dim; 74 | 75 | // Explicit cast to 2-dim Type array 76 | // Compiles but throws InvalidCastException at runtime 77 | try { 78 | Type[,] t2dim = (Type[,])o2dim; 79 | } 80 | catch (InvalidCastException) { 81 | } 82 | 83 | // Create a 1-dim Int32 array (value types) 84 | Int32[] i1dim = new Int32[5]; 85 | 86 | // Can't cast from array of value types to anything else 87 | // Compiler error CS0030: Cannot convert type 'int[]' to 'object[]' 88 | // Object[] o1dim = (Object[]) i1dim; 89 | 90 | // However, Array.Copy knows how to coerce an array 91 | // of value types to an array of boxed references 92 | Object[] o1dim = new Object[i1dim.Length]; 93 | Array.Copy(i1dim, o1dim, 0); 94 | } 95 | 96 | private static void DynamicArray() { 97 | // We want a 2-dim array 98 | Int32[] lowerBounds = { 1995, 1 }; 99 | Int32[] lengths = { 10, 4 }; 100 | Decimal[,] quarterlyRevenue = (Decimal[,]) 101 | Array.CreateInstance(typeof(Decimal), lengths, lowerBounds); 102 | 103 | Int32 firstYear = quarterlyRevenue.GetLowerBound(0); 104 | Int32 lastYear = quarterlyRevenue.GetUpperBound(0); 105 | Console.WriteLine("{0,4} {1,9} {2,9} {3,9} {4,9}", "Year", "Q1", "Q2", "Q3", "Q4"); 106 | 107 | Random r = new Random(); 108 | for (Int32 year = firstYear; year <= lastYear; year++) { 109 | Console.Write(year + " "); 110 | 111 | for (Int32 quarter = quarterlyRevenue.GetLowerBound(1); quarter <= quarterlyRevenue.GetUpperBound(1); quarter++) { 112 | quarterlyRevenue[year, quarter] = r.Next(10000); 113 | 114 | Console.Write("{0,9:C} ", quarterlyRevenue[year, quarter]); 115 | } 116 | Console.WriteLine(); 117 | } 118 | } 119 | } 120 | 121 | internal static class DynamicArrays { 122 | public static void Go() { 123 | // I want a two-dimension array [2005..2009][1..4]. 124 | Int32[] lowerBounds = { 2005, 1 }; 125 | Int32[] lengths = { 5, 4 }; 126 | Decimal[,] quarterlyRevenue = (Decimal[,]) 127 | Array.CreateInstance(typeof(Decimal), lengths, lowerBounds); 128 | 129 | Console.WriteLine("{0,4} {1,9} {2,9} {3,9} {4,9}", 130 | "Year", "Q1", "Q2", "Q3", "Q4"); 131 | Int32 firstYear = quarterlyRevenue.GetLowerBound(0); 132 | Int32 lastYear = quarterlyRevenue.GetUpperBound(0); 133 | Int32 firstQuarter = quarterlyRevenue.GetLowerBound(1); 134 | Int32 lastQuarter = quarterlyRevenue.GetUpperBound(1); 135 | 136 | for (Int32 year = firstYear; year <= lastYear; year++) { 137 | Console.Write(year + " "); 138 | for (Int32 quarter = firstQuarter; quarter <= lastQuarter; quarter++) { 139 | Console.Write("{0,9:C} ", quarterlyRevenue[year, quarter]); 140 | } 141 | Console.WriteLine(); 142 | } 143 | } 144 | } 145 | 146 | internal static class ArrayTypes { 147 | public static void Go() { 148 | Array a; 149 | 150 | // Create a 1-dim, 0-based array, with no elements in it 151 | a = new String[0]; 152 | Console.WriteLine(a.GetType()); // System.String[] 153 | 154 | // Create a 1-dim, 0-based array, with no elements in it 155 | a = Array.CreateInstance(typeof(String), new Int32[] { 0 }, new Int32[] { 0 }); 156 | Console.WriteLine(a.GetType()); // System.String[] 157 | 158 | // Create a 1-dim, 1-based array, with no elements in it 159 | a = Array.CreateInstance(typeof(String), new Int32[] { 0 }, new Int32[] { 1 }); 160 | Console.WriteLine(a.GetType()); // System.String[*] <-- INTERESTING! 161 | 162 | Console.WriteLine(); 163 | 164 | // Create a 2-dim, 0-based array, with no elements in it 165 | a = new String[0, 0]; 166 | Console.WriteLine(a.GetType()); // System.String[,] 167 | 168 | // Create a 2-dim, 0-based array, with no elements in it 169 | a = Array.CreateInstance(typeof(String), new Int32[] { 0, 0 }, new Int32[] { 0, 0 }); 170 | Console.WriteLine(a.GetType()); // System.String[,] 171 | 172 | // Create a 2-dim, 1-based array, with no elements in it 173 | a = Array.CreateInstance(typeof(String), new Int32[] { 0, 0 }, new Int32[] { 1, 1 }); 174 | Console.WriteLine(a.GetType()); // System.String[,] 175 | } 176 | } 177 | 178 | internal static class MultiDimArrayPerformance { 179 | private const Int32 c_numElements = 10000; 180 | 181 | public static void Go() { 182 | // Declare a 2-dimensional array 183 | Int32[,] a2Dim = new Int32[c_numElements, c_numElements]; 184 | 185 | // Declare a 2-dimensional array as a jagged array (a vector of vectors) 186 | Int32[][] aJagged = new Int32[c_numElements][]; 187 | for (Int32 x = 0; x < c_numElements; x++) 188 | aJagged[x] = new Int32[c_numElements]; 189 | 190 | 191 | // 1: Access all elements of the array using the usual, safe technique 192 | Safe2DimArrayAccess(a2Dim); 193 | 194 | // 2: Access all elements of the array using the jagged array technique 195 | SafeJaggedArrayAccess(aJagged); 196 | 197 | // 3: Access all elements of the array using the unsafe technique 198 | Unsafe2DimArrayAccess(a2Dim); 199 | } 200 | 201 | private static Int32 Safe2DimArrayAccess(Int32[,] a) { 202 | Int32 sum = 0; 203 | for (Int32 x = 0; x < c_numElements; x++) { 204 | for (Int32 y = 0; y < c_numElements; y++) { 205 | sum += a[x, y]; 206 | } 207 | } 208 | return sum; 209 | } 210 | 211 | private static Int32 SafeJaggedArrayAccess(Int32[][] a) { 212 | Int32 sum = 0; 213 | for (Int32 x = 0; x < c_numElements; x++) { 214 | for (Int32 y = 0; y < c_numElements; y++) { 215 | sum += a[x][y]; 216 | } 217 | } 218 | return sum; 219 | } 220 | 221 | private static unsafe Int32 Unsafe2DimArrayAccess(Int32[,] a) { 222 | Int32 sum = 0, numElements = c_numElements * c_numElements; 223 | fixed (Int32* pi = a) { 224 | for (Int32 x = 0; x < numElements; x++) { 225 | sum += pi[x]; 226 | } 227 | } 228 | return sum; 229 | } 230 | } 231 | 232 | internal static class StackallocAndInlineArrays { 233 | public static void Go() { 234 | StackallocDemo(); 235 | InlineArrayDemo(); 236 | } 237 | 238 | private static void StackallocDemo() { 239 | unsafe { 240 | const Int32 width = 20; 241 | Char* pc = stackalloc Char[width]; // Allocates array on stack 242 | 243 | String s = "Jeffrey Richter"; // 15 characters 244 | 245 | for (Int32 index = 0; index < width; index++) { 246 | pc[width - index - 1] = 247 | (index < s.Length) ? s[index] : '.'; 248 | } 249 | Console.WriteLine(new String(pc, 0, width)); // ".....rethciR yerffeJ" 250 | } 251 | } 252 | 253 | private static void InlineArrayDemo() { 254 | unsafe { 255 | CharArray ca; // Allocates array on stack 256 | Int32 widthInBytes = sizeof(CharArray); 257 | Int32 width = widthInBytes / 2; 258 | 259 | String s = "Jeffrey Richter"; // 15 characters 260 | 261 | for (Int32 index = 0; index < width; index++) { 262 | ca.Characters[width - index - 1] = 263 | (index < s.Length) ? s[index] : '.'; 264 | } 265 | Console.WriteLine(new String(ca.Characters, 0, width)); // ".....rethciR yerffeJ" 266 | } 267 | } 268 | 269 | private unsafe struct CharArray { 270 | // This array is embedded inline inside the structure 271 | public fixed Char Characters[20]; 272 | } 273 | } 274 | 275 | 276 | //////////////////////////////// End of File ////////////////////////////////// 277 | -------------------------------------------------------------------------------- /Ch16-1-Arrays.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {2237152B-00AF-472B-81EC-3AA23A3FF698} 9 | Exe 10 | Properties 11 | Arrays 12 | Ch16-1-Arrays 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | true 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | true 43 | false 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Ch17-1-Delegates.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch17-1-Delegates.cs -------------------------------------------------------------------------------- /Ch17-1-Delegates.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {6A0E4BED-2E12-413F-801F-7E02ACA50D45} 9 | Exe 10 | Properties 11 | Delegates 12 | Ch17-1-Delegates 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Ch18-1-CustomAttributes.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch18-1-CustomAttributes.cs -------------------------------------------------------------------------------- /Ch18-1-CustomAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {B341EFC0-FEE4-4F2B-A4B5-D64F21C7F6F5} 9 | Exe 10 | Properties 11 | CustomAttributes 12 | Ch18-1-CustomAttributes 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | AllRules.ruleset 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Ch19-1-NullableValueTypes.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch19-1-NullableValueTypes.cs -------------------------------------------------------------------------------- /Ch19-1-NullableValueTypes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {56AA0815-65DC-4CCE-81F5-E9146C9B3726} 9 | Exe 10 | Properties 11 | NullableValueTypes 12 | Ch19-1-NullableValueTypes 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /Ch20-1-ExceptionHandling.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {AEC7D22E-756B-4679-B28E-5808848EF132} 9 | Exe 10 | Properties 11 | Ch20_1_ExceptionHandling 12 | Ch20-1-ExceptionHandling 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 0 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | True 29 | 30 | 31 | Full 32 | False 33 | True 34 | False 35 | False 36 | False 37 | False 38 | False 39 | False 40 | False 41 | False 42 | 43 | 44 | 45 | 46 | False 47 | True 48 | False 49 | Build 50 | false 51 | false 52 | 53 | 54 | pdbonly 55 | true 56 | bin\Release\ 57 | TRACE 58 | prompt 59 | 4 60 | false 61 | false 62 | True 63 | False 64 | False 65 | False 66 | False 67 | False 68 | False 69 | False 70 | False 71 | False 72 | False 73 | False 74 | False 75 | False 76 | False 77 | True 78 | False 79 | False 80 | True 81 | True 82 | False 83 | False 84 | 85 | 86 | 87 | 88 | 89 | 90 | True 91 | Full 92 | Build 93 | 0 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 114 | -------------------------------------------------------------------------------- /Ch21-1-GarbageCollection.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {1D2BF940-7E79-44C2-9F82-C549470F2B68} 9 | Exe 10 | Properties 11 | Ch21_1_GarbageCollection 12 | Ch21-1-GarbageCollection 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | true 28 | false 29 | true 30 | false 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | true 40 | false 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Ch22-1-AppDomains.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Reflection; 5 | using System.Runtime.InteropServices; 6 | using System.Runtime.Remoting; 7 | using System.Threading; 8 | 9 | public sealed class Program { 10 | public static void Main() { 11 | //Marshalling(); 12 | FieldAccessTiming(); 13 | AppDomainResourceMonitoring(); 14 | UnloadTimeout.Go(); 15 | } 16 | 17 | private static void Marshalling() { 18 | // Get a reference to the AppDomain that that calling thread is executing in 19 | AppDomain adCallingThreadDomain = Thread.GetDomain(); 20 | 21 | // Every AppDomain is assigned a friendly string name (helpful for debugging) 22 | // Get this AppDomain's friendly string name and display it 23 | String callingDomainName = adCallingThreadDomain.FriendlyName; 24 | Console.WriteLine("Default AppDomain's friendly name={0}", callingDomainName); 25 | 26 | // Get & display the assembly in our AppDomain that contains the 'Main' method 27 | String exeAssembly = Assembly.GetEntryAssembly().FullName; 28 | Console.WriteLine("Main assembly={0}", exeAssembly); 29 | 30 | // Define a local variable that can refer to an AppDomain 31 | AppDomain ad2 = null; 32 | 33 | // *** DEMO 1: Cross-AppDomain Communication using Marshal-by-Reference 34 | Console.WriteLine("{0}Demo #1", Environment.NewLine); 35 | 36 | // Create new AppDomain (security & configuration match current AppDomain) 37 | ad2 = AppDomain.CreateDomain("AD #2", null, null); 38 | MarshalByRefType mbrt = null; 39 | 40 | // Load our assembly into the new AppDomain, construct an object, marshal 41 | // it back to our AD (we really get a reference to a proxy) 42 | mbrt = (MarshalByRefType) 43 | ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); 44 | 45 | Console.WriteLine("Type={0}", mbrt.GetType()); // The CLR lies about the type 46 | 47 | // Prove that we got a reference to a proxy object 48 | Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); 49 | 50 | // This looks like we're calling a method on MarshalByRefType but, we're not. 51 | // We're calling a method on the proxy type. The proxy transitions the thread 52 | // to the AppDomain owning the object and calls this method on the real object. 53 | mbrt.SomeMethod(); 54 | 55 | // Unload the new AppDomain 56 | AppDomain.Unload(ad2); 57 | // mbrt refers to a valid proxy object; the proxy object refers to an invalid AppDomain 58 | 59 | try { 60 | // We're calling a method on the proxy type. The AD is invalid, exception is thrown 61 | mbrt.SomeMethod(); 62 | Console.WriteLine("Successful call."); 63 | } 64 | catch (AppDomainUnloadedException) { 65 | Console.WriteLine("Failed call."); 66 | } 67 | 68 | 69 | // *** DEMO 2: Cross-AppDomain Communication using Marshal-by-Value 70 | Console.WriteLine("{0}Demo #2", Environment.NewLine); 71 | 72 | // Create new AppDomain (security & configuration match current AppDomain) 73 | ad2 = AppDomain.CreateDomain("AD #2", null, null); 74 | 75 | // Load our assembly into the new AppDomain, construct an object, marshal 76 | // it back to our AD (we really get a reference to a proxy) 77 | mbrt = (MarshalByRefType) 78 | ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); 79 | 80 | // The object's method returns a COPY of the returned object; 81 | // the object is marshaled by value (not be reference). 82 | MarshalByValType mbvt = mbrt.MethodWithReturn(); 83 | 84 | // Prove that we did NOT get a reference to a proxy object 85 | Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt)); 86 | 87 | // This looks like we're calling a method on MarshalByValType and we are. 88 | Console.WriteLine("Returned object created " + mbvt.ToString()); 89 | 90 | // Unload the new AppDomain 91 | AppDomain.Unload(ad2); 92 | // mbvt refers to valid object; unloading the AppDomain has no impact. 93 | 94 | try { 95 | // We're calling a method on an object; no exception is thrown 96 | Console.WriteLine("Returned object created " + mbvt.ToString()); 97 | Console.WriteLine("Successful call."); 98 | } 99 | catch (AppDomainUnloadedException) { 100 | Console.WriteLine("Failed call."); 101 | } 102 | 103 | 104 | // DEMO 3: Cross-AppDomain Communication using non-marshalable type 105 | Console.WriteLine("{0}Demo #3", Environment.NewLine); 106 | 107 | // Create new AppDomain (security & configuration match current AppDomain) 108 | ad2 = AppDomain.CreateDomain("AD #2", null, null); 109 | 110 | // Load our assembly into the new AppDomain, construct an object, marshal 111 | // it back to our AD (we really get a reference to a proxy) 112 | mbrt = (MarshalByRefType) 113 | ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType"); 114 | 115 | // The object's method returns an non-marshalable object; exception 116 | NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName); 117 | // We won't get here... 118 | } 119 | 120 | private sealed class MBRO : MarshalByRefObject { public Int32 x; } 121 | private sealed class NonMBRO : Object { public Int32 x; } 122 | 123 | private static void FieldAccessTiming() { 124 | const Int32 count = 100000000; 125 | NonMBRO nonMbro = new NonMBRO(); 126 | MBRO mbro = new MBRO(); 127 | 128 | Stopwatch sw = Stopwatch.StartNew(); 129 | for (Int32 c = 0; c < count; c++) nonMbro.x++; 130 | Console.WriteLine("{0}", sw.Elapsed); 131 | 132 | sw = Stopwatch.StartNew(); 133 | for (Int32 c = 0; c < count; c++) mbro.x++; 134 | Console.WriteLine("{0}", sw.Elapsed); 135 | } 136 | 137 | private sealed class AppDomainMonitorDelta : IDisposable { 138 | private AppDomain m_appDomain; 139 | private TimeSpan m_thisADCpu; 140 | private Int64 m_thisADMemoryInUse; 141 | private Int64 m_thisADMemoryAllocated; 142 | 143 | static AppDomainMonitorDelta() { 144 | // Make sure that AppDomain monitoring is turned on 145 | AppDomain.MonitoringIsEnabled = true; 146 | } 147 | 148 | public AppDomainMonitorDelta(AppDomain ad) { 149 | m_appDomain = ad ?? AppDomain.CurrentDomain; 150 | m_thisADCpu = m_appDomain.MonitoringTotalProcessorTime; 151 | m_thisADMemoryInUse = m_appDomain.MonitoringSurvivedMemorySize; 152 | m_thisADMemoryAllocated = m_appDomain.MonitoringTotalAllocatedMemorySize; 153 | } 154 | 155 | public void Dispose() { 156 | GC.Collect(); 157 | Console.WriteLine("FriendlyName={0}, CPU={1}ms", 158 | m_appDomain.FriendlyName, 159 | (m_appDomain.MonitoringTotalProcessorTime - m_thisADCpu).TotalMilliseconds); 160 | 161 | Console.WriteLine(" Allocated {0:N0} bytes of which {1:N0} survived GCs", 162 | m_appDomain.MonitoringTotalAllocatedMemorySize - m_thisADMemoryAllocated, 163 | m_appDomain.MonitoringSurvivedMemorySize - m_thisADMemoryInUse); 164 | } 165 | } 166 | 167 | private static void AppDomainResourceMonitoring() { 168 | using (new AppDomainMonitorDelta(null)) { 169 | // Allocate about 10 million bytes that will survive collections 170 | var list = new List(); 171 | for (Int32 x = 0; x < 1000; x++) list.Add(new Byte[10000]); 172 | 173 | // Allocate about 20 million bytes that will NOT survive collections 174 | for (Int32 x = 0; x < 2000; x++) new Byte[10000].GetType(); 175 | 176 | // Spin the CPU for about 5 seconds 177 | Int64 stop = Environment.TickCount + 5000; 178 | while (Environment.TickCount < stop) ; 179 | } 180 | } 181 | 182 | private static class UnloadTimeout { 183 | private static Int32 s_testCode = 0; // 0=InfiniteLoop, 1=ManagedSleep, 2=UnmanagedSleep 184 | private static AppDomain s_ad; 185 | 186 | public static void Go() { 187 | // Create an AppDomain 188 | s_ad = AppDomain.CreateDomain("AD #2", null, null); 189 | 190 | // Spawn thread to enter the other AppDomain 191 | Thread t = new Thread((ThreadStart)delegate { s_ad.DoCallBack(Loop); }); 192 | t.Start(); 193 | Thread.Sleep(5000); // The other thread a chance to run 194 | 195 | Stopwatch sw = null; 196 | try { 197 | // Time how long it takes to unload the AppDomain 198 | Console.WriteLine("Calling unload"); 199 | sw = Stopwatch.StartNew(); 200 | AppDomain.Unload(s_ad); 201 | } 202 | catch (Exception e) { 203 | Console.WriteLine(e.ToString()); 204 | } 205 | Console.WriteLine("Unload returned after {0}", sw.Elapsed); 206 | Console.ReadLine(); 207 | } 208 | 209 | private static void Loop() { 210 | try { 211 | switch (s_testCode) { 212 | case 0: while (true) ; // Infinite loop 213 | case 1: Thread.Sleep(10000); break; // Managed sleep 214 | case 2: Sleep(10000); break; // Unmanaged sleep 215 | } 216 | } 217 | catch (ThreadAbortException) { 218 | Console.WriteLine("Caught ThreadAbortException: Hit return to exit"); 219 | Console.ReadLine(); 220 | } 221 | } 222 | 223 | [DllImport("Kernel32")] 224 | private static extern void Sleep(UInt32 ms); 225 | } 226 | } 227 | 228 | 229 | // Instances can be marshaled-by-reference across AppDomain boundaries 230 | public sealed class MarshalByRefType : MarshalByRefObject { 231 | public MarshalByRefType() { 232 | Console.WriteLine("{0} ctor running in {1}", 233 | this.GetType().ToString(), Thread.GetDomain().FriendlyName); 234 | } 235 | 236 | public void SomeMethod() { 237 | Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); 238 | } 239 | 240 | public MarshalByValType MethodWithReturn() { 241 | Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); 242 | MarshalByValType t = new MarshalByValType(); 243 | return t; 244 | } 245 | 246 | public NonMarshalableType MethodArgAndReturn(String callingDomainName) { 247 | // NOTE: callingDomainName is [Serializable] 248 | Console.WriteLine("Calling from '{0}' to '{1}'.", 249 | callingDomainName, Thread.GetDomain().FriendlyName); 250 | NonMarshalableType t = new NonMarshalableType(); 251 | return t; 252 | } 253 | 254 | [DebuggerStepThrough] 255 | public override Object InitializeLifetimeService() { 256 | return null; // We want an infinite lifetime 257 | } 258 | } 259 | 260 | 261 | // Instances can be marshaled-by-value across AppDomain boundaries 262 | [Serializable] 263 | public sealed class MarshalByValType : Object { 264 | private DateTime m_creationTime = DateTime.Now; // NOTE: DateTime is [Serializable] 265 | 266 | public MarshalByValType() { 267 | Console.WriteLine("{0} ctor running in {1}, Created on {2:D}", 268 | this.GetType().ToString(), 269 | Thread.GetDomain().FriendlyName, 270 | m_creationTime); 271 | } 272 | 273 | public override String ToString() { 274 | return m_creationTime.ToLongDateString(); 275 | } 276 | } 277 | 278 | // Instances cannot be marshaled across AppDomain boundaries 279 | // [Serializable] 280 | public sealed class NonMarshalableType : Object { 281 | public NonMarshalableType() { 282 | Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName); 283 | } 284 | } -------------------------------------------------------------------------------- /Ch22-1-AppDomains.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {D8B65EF3-851D-4BE0-BBB5-5C0D586F7EA7} 9 | Exe 10 | Properties 11 | AppDomains 12 | Ch22-1-AppDomains 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | false 31 | AllRules.ruleset 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Ch23-1-AssemblyLoadingAndReflection.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {8574B0B4-C843-40D7-A6F9-66EB8F4F613D} 9 | Exe 10 | Properties 11 | AssemblyLoadingAndReflection 12 | Ch23-1-AssemblyLoadingAndReflection 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | AllRules.ruleset 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | False 53 | ..\..\..\..\..\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Microsoft.CSharp.dll 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {03634A5F-09FF-47D5-8BAF-3430B87561D8} 62 | Ch01-1-SomeLibrary 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /Ch23-2-AddIn_SDKAssembly.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Wintellect.HostSDK { 4 | public interface IAddIn { 5 | String DoSomething(Int32 x); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Ch23-2-AddIn_SDKAssembly.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {FAFD6BEE-33F3-476B-9F86-5D054C7CA219} 9 | Library 10 | Properties 11 | AddIn_SDKAssembly 12 | Ch23-2-AddIn_SDKAssembly 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /Ch23-3-AddIn_AddInTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Wintellect.HostSDK; 3 | 4 | public class AddIn_A : IAddIn { 5 | public AddIn_A() { 6 | } 7 | public String DoSomething(Int32 x) { 8 | return "AddIn_A: " + x.ToString(); 9 | } 10 | } 11 | 12 | public class AddIn_B : IAddIn { 13 | public AddIn_B() { 14 | } 15 | public String DoSomething(Int32 x) { 16 | return "AddIn_B: " + (x * 2).ToString(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Ch23-3-AddIn_AddInTypes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {D3DFAFDC-A040-4959-B43F-64AB03CB0181} 9 | Library 10 | Properties 11 | AddIn_AddInType 12 | Ch23-3-AddIn_AddInType 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | false 42 | 43 | 44 | 45 | {FAFD6BEE-33F3-476B-9F86-5D054C7CA219} 46 | Ch23-2-AddIn_SDKAssembly 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /Ch23-4-AddIn_Host.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.IO; 4 | using System.Reflection; 5 | using System.Collections.Generic; 6 | using Wintellect.HostSDK; 7 | 8 | public sealed class Program { 9 | public static void Main() { 10 | // Find the directory that contains the Host exe 11 | String AddInDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); 12 | 13 | // Assume AddIn assemblies are in same directory as host's EXE file 14 | var AddInAssemblies = Directory.EnumerateFiles(AddInDir, "*.dll"); 15 | 16 | // Create a collection of Add-In Types usable by the host 17 | var AddInTypes = 18 | from file in AddInAssemblies 19 | let assembly = Assembly.Load(file) 20 | from t in assembly.ExportedTypes // Publicly-exported types 21 | // Type is usable if it is a class that implements IAddIn 22 | where t.IsClass && typeof(IAddIn).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()) 23 | select t; 24 | // Initialization complete: the host has discovered the usable Add-Ins 25 | 26 | // Here's how the host can construct Add-In objects and use them 27 | foreach (Type t in AddInTypes) { 28 | IAddIn ai = (IAddIn) Activator.CreateInstance(t); 29 | Console.WriteLine(ai.DoSomething(5)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Ch23-4-AddIn_Host.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {2CFFF3F7-AA6F-46F1-A70A-F9917002C607} 9 | Exe 10 | Properties 11 | AddInHost 12 | Ch23-4-AddInHost 13 | 14 | 15 | 3.5 16 | 17 | 18 | v4.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | AllRules.ruleset 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | AllRules.ruleset 41 | true 42 | true 43 | false 44 | 45 | 46 | 47 | {FAFD6BEE-33F3-476B-9F86-5D054C7CA219} 48 | Ch23-2-AddIn_SDKAssembly 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /Ch24-1-RuntimeSerialization.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {E64BE8E6-5BF2-411C-BFFA-D7ED0470E009} 9 | Exe 10 | Properties 11 | Ch24_1_RuntimeSerialization 12 | Ch24-1-RuntimeSerialization 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | true 27 | false 28 | false 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /Ch25-1-WinRTComponents.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8.0.30703 8 | 2.0 9 | {66FF2B7A-4B2D-4879-A151-659610686371} 10 | winmdobj 11 | Properties 12 | Wintellect.WinRTComponents 13 | Wintellect.WinRTComponents 14 | en-US 15 | 512 16 | {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE;NETFX_CORE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE;NETFX_CORE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | bin\ARM\Debug\ 38 | DEBUG;TRACE;NETFX_CORE 39 | ;2008 40 | full 41 | ARM 42 | false 43 | prompt 44 | true 45 | 46 | 47 | bin\ARM\Release\ 48 | TRACE;NETFX_CORE 49 | true 50 | ;2008 51 | pdbonly 52 | ARM 53 | false 54 | prompt 55 | true 56 | 57 | 58 | true 59 | bin\x64\Debug\ 60 | DEBUG;TRACE;NETFX_CORE 61 | ;2008 62 | full 63 | x64 64 | false 65 | prompt 66 | true 67 | 68 | 69 | bin\x64\Release\ 70 | TRACE;NETFX_CORE 71 | true 72 | ;2008 73 | pdbonly 74 | x64 75 | false 76 | prompt 77 | true 78 | 79 | 80 | true 81 | bin\x86\Debug\ 82 | DEBUG;TRACE;NETFX_CORE 83 | ;2008 84 | full 85 | x86 86 | false 87 | prompt 88 | true 89 | 90 | 91 | bin\x86\Release\ 92 | TRACE;NETFX_CORE 93 | true 94 | ;2008 95 | pdbonly 96 | x86 97 | false 98 | prompt 99 | true 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 11.0 110 | 111 | 112 | 119 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/Ch25-2-ConsumeWinRTComponents.jsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | Debug 10 | ARM 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Debug 18 | x86 19 | 20 | 21 | Release 22 | AnyCPU 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Release 30 | x64 31 | 32 | 33 | Release 34 | x86 35 | 36 | 37 | 38 | 37271c44-feee-48c0-9fb7-cf777d5062df 39 | 40 | 41 | 42 | 43 | 44 | Windows 45 | 8.0 46 | en-US 47 | PublisherCertificate.pfx 48 | AE81427B7B51119CFA1A3ED0491CFA45C40398B1 49 | 50 | 51 | 52 | Designer 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 77 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/Ch25-2-ConsumeWinRTComponents.jsproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | C:\Users\Jeffrey\AppData\Local\Temp\wh4ers4h_Ch25-2-ConsumeWinRTComponents_refcache 5 | 6 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/PublisherCertificate.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch25-2-ConsumeWinRTComponents/PublisherCertificate.pfx -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/css/default.css: -------------------------------------------------------------------------------- 1 | body { 2 | } 3 | 4 | @media screen and (-ms-view-state: fullscreen-landscape) { 5 | } 6 | 7 | @media screen and (-ms-view-state: filled) { 8 | } 9 | 10 | @media screen and (-ms-view-state: snapped) { 11 | } 12 | 13 | @media screen and (-ms-view-state: fullscreen-portrait) { 14 | } 15 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JavaScript Client using WinRT Component 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Access WinRT Components (step in debugger to see it work) 24 | 25 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/images/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch25-2-ConsumeWinRTComponents/images/Logo.png -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/images/SmallLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch25-2-ConsumeWinRTComponents/images/SmallLogo.png -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/images/SplashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch25-2-ConsumeWinRTComponents/images/SplashScreen.png -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/images/storelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuicheng11165/clr-via-csharp-4th-edition-code/d2b48541d967765ab5081c77409159cfcc88267b/Ch25-2-ConsumeWinRTComponents/images/storelogo.png -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/js/default.js: -------------------------------------------------------------------------------- 1 | // For an introduction to the Blank template, see the following documentation: 2 | // http://go.microsoft.com/fwlink/?LinkId=232509 3 | (function () { 4 | "use strict"; 5 | 6 | var app = WinJS.Application; 7 | var activation = Windows.ApplicationModel.Activation; 8 | WinJS.strictProcessing(); 9 | 10 | app.onactivated = function (args) { 11 | if (args.detail.kind === activation.ActivationKind.launch) { 12 | if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { 13 | // TODO: This application has been newly launched. Initialize 14 | // your application here. 15 | } else { 16 | // TODO: This application has been reactivated from suspension. 17 | // Restore application state here. 18 | } 19 | args.setPromise(WinJS.UI.processAll()); 20 | } 21 | }; 22 | 23 | app.oncheckpoint = function (args) { 24 | // TODO: This application is about to be suspended. Save any state 25 | // that needs to persist across suspensions here. You might use the 26 | // WinJS.Application.sessionState object, which is automatically 27 | // saved and restored across suspension. If you need to complete an 28 | // asynchronous operation before your application is suspended, call 29 | // args.setPromise(). 30 | }; 31 | 32 | app.start(); 33 | })(); 34 | -------------------------------------------------------------------------------- /Ch25-2-ConsumeWinRTComponents/package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Access WinRT Comp via JS 6 | Jeffrey 7 | images\storelogo.png 8 | 9 | 10 | 6.2.0 11 | 6.2.0 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Ch26-1-ThreadBasics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | public static class ThreadBasics { 5 | public static void Main() { 6 | FirstThread.Go(); 7 | BackgroundDemo.Go(true); 8 | BackgroundDemo.Go(false); 9 | } 10 | } 11 | 12 | internal static class FirstThread { 13 | public static void Go() { 14 | Console.WriteLine("Main thread: starting a dedicated thread " + 15 | "to do an asynchronous operation"); 16 | Thread dedicatedThread = new Thread(ComputeBoundOp); 17 | dedicatedThread.Start(5); 18 | 19 | Console.WriteLine("Main thread: Doing other work here..."); 20 | Thread.Sleep(10000); // Simulating other work (10 seconds) 21 | 22 | dedicatedThread.Join(); // Wait for thread to terminate 23 | Console.ReadLine(); 24 | } 25 | 26 | // This method's signature must match the ParametizedThreadStart delegate 27 | private static void ComputeBoundOp(Object state) { 28 | // This method is executed by another thread 29 | 30 | Console.WriteLine("In ComputeBoundOp: state={0}", state); 31 | Thread.Sleep(1000); // Simulates other work (1 second) 32 | 33 | // When this method returns, the dedicated thread dies 34 | } 35 | } 36 | 37 | internal static class BackgroundDemo { 38 | public static void Go(Boolean background) { 39 | // Create a new thread (defaults to Foreground) 40 | Thread t = new Thread(new ThreadStart(ThreadMethod)); 41 | 42 | // Make the thread a background thread if desired 43 | if (background) t.IsBackground = true; 44 | 45 | t.Start(); // Start the thread 46 | return; // NOTE: the application won't actually die for about 10 seconds 47 | } 48 | 49 | private static void ThreadMethod() { 50 | Thread.Sleep(10000); // Simulate 10 seconds of work 51 | Console.WriteLine("ThreadMethod is exiting"); 52 | } 53 | } -------------------------------------------------------------------------------- /Ch26-1-ThreadBasics.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {D2BA9EC8-9B76-4441-8E58-1102788407BE} 9 | Exe 10 | Properties 11 | Ch26_1_ThreadBasics 12 | Ch26-1-ThreadBasics 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | false 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 4.0 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Ch27-1-ComputeOps.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {65719739-D936-4B94-8654-9EF46B835C69} 9 | Exe 10 | Properties 11 | Ch27_1_ComputeOps 12 | Ch27-1-ComputeOps 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | false 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 4.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /Ch28-1-IOOps.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {C47AB646-986E-4EA5-B09D-6CBA602290E2} 9 | Exe 10 | Properties 11 | Ch28_IOOps 12 | Ch28-1-IOOps 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | false 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 3.5 46 | 47 | 48 | 49 | 50 | 51 | 52 | ..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\WindowsBase.dll 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /Ch29-1-PrimitveThreadSync.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {D2FF3909-FD50-4B2B-A764-6B4FC0FDE6A2} 9 | Exe 10 | Properties 11 | Ch29_1_PrimitveThreadSync 12 | Ch29-1-PrimitveThreadSync 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | true 28 | x86 29 | false 30 | 31 | 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | false 39 | false 40 | 41 | 42 | 43 | 44 | 3.5 45 | 46 | 47 | 4.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /Ch30-1-HybridThreadSync.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 10.0.20506 7 | 2.0 8 | {A7275EC7-1101-4D9E-8796-7479035E7AE5} 9 | Exe 10 | Properties 11 | Ch30_1_HybridThreadSync 12 | Ch30-1-HybridThreadSync 13 | v4.5 14 | 512 15 | x86 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | false 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 4.0 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clr via c# 里面的代码及其阅读笔记 2 | 3 | 阅读策略 4 | 5 | * 作者:赵劼 来源:知乎 (https://www.zhihu.com/question/27283360/answer/36182906) 6 | 7 | * 细读:都要读懂,要都理解了,读不懂反复读,找额外资料读。 8 | * 通读:大致都了解可以干嘛,尽量看懂。 9 | * 粗读:随手翻下,读不懂可以跳过,时不时回头看看。 10 | 11 | * Ch1通读。 12 | * Ch2和3粗读。 13 | * Ch4到19:细读,全是基础内容。 14 | * Ch20细读,最后两节(CER和Code Contract)可以粗读。 15 | * Ch21细读,讲GC的,比较重要。 16 | * Ch22粗读。 17 | * Ch23到25通读。 18 | * Ch26细读。 19 | * Ch27到30通读。 20 | 21 | * 30章,每2天1章,大概需要2个月 22 | 23 | 24 | --------------------------------------------------------------------------------