This project is aimed to help the user further study C# with a test-driven approach. Each unit contains an annotated tutorial and a platform where you can test your understanding of the topic.
Topics:
using System; //Use 'using' keyword to tell the compiler that you are using the 'System' namespace namespace Fundamentals //'namespace' is a special keyword that allows to separate the code in a meaninful manner { class LearnThisFirst //Every single time you want to execute code, it needs to be inside of a Type, in this case, a Class { static void Main() //The 'Main' method that will execute first when running a console application { //Every Object you work with, has a type, in this case, it is a System.Int type, which we use the keyword 'int' to represent it int firstType = 3; //Your first Type Console.WriteLine("Hello World"); //Your first statement, this will output to console 'Hello World' int sum = 3 + 3;// '3+3' is an expression statement since it evaluates and creates a value /*When writting Console Applications, you can use 'Console.ReadLine()' statement to wait for User Input, then the CMD Window won't automatically close*/ Console.ReadLine();
[TestMethod] [ExpectedException(typeof(OutOfMemoryException))] public void OutOfMemory() { var csharpList = new List<CsharpClass>(); for (var i = 0; i < 9000000; i++) //We increment the number of loops to create an OutOfMemoryException { var csharp = new CsharpClass(i.ToString(CultureInfo.InvariantCulture)); csharpList.Add(csharp); } //Performance is affected severely and program will never reach this point *On most commercial machines Assert.IsTrue(GetTotalCollections() < 403); } private static int GetTotalCollections() //How many GB collections ran in all generations { // 0 - When we first create an object, the references are placed in generation zero // 1 - If reference survives when the generatrion zero collection is placed, then the reference is placed on generation 1 // 2 - If the references survive a collection on pass 1, they will be placed on generation 2 return GC.CollectionCount(0) + GC.CollectionCount(1) + GC.CollectionCount(2); //We need to print the 3 generations of Garbage Collection }
[TestMethod] public void DefaultKeyword() //The default keyword is used in a context where you do not know the Type at runtime { // default of Referenece Types is Null Assert.IsNull(ReturnDefault<ImplementsIDisposable>()); // default of Value Numeric types is generally 0 Assert.IsTrue(ReturnDefault<int>() == 0); } private static object CreateDisposer(Type type) { var implementsIDisposableType = typeof (Disposer<>); //This is an unbound generic type return Activator.CreateInstance(implementsIDisposableType.MakeGenericType(type)); //We get the type at runtime via the Type parameter } //You can specify the T of the returned value private static Disposer<T> CreateDisposer<T>() where T : IDisposable //You can create Generic methods as well, with the same constrains as the class { var implementsIDisposableType = typeof(Disposer<>); return Activator.CreateInstance(implementsIDisposableType.MakeGenericType(typeof(T))) as Disposer<T>; //We get the type at runtime via the T Type } private static T ReturnDefault<T>() { return default(T);//This could be null or 0 *for most Int types } } } internal class Disposer<TDisposer> where TDisposer : IDisposable // You can set conditions on the Generic Type in order to perform more activities with the given instance at runtime { public bool Dispose(TDisposer item) { item.Dispose(); return true; } } internal class ImplementsIDisposable : IDisposable //This is a class that implements IDisposable { public void Dispose() //This gets executed at runtime by the Disposer Class { } }Reflection: Code Generation
In this example we explain the use of Reflection and how to dynamically create code using C# / .Net
[TestMethod] public void DynamicallyCreatingCode() { //The method ‘GetMethod’ extracts the method information from Debug.Writeline var methodInfo = typeof(Debug).GetMethod("WriteLine", new[] { typeof(string) }); //We can specify the method signature by using a type of DynamicMethod var dynamicMethod = new DynamicMethod("DynamicMethod", typeof(void), new Type[] { }); //We use 'GetILGenerator()' in order to create IL statements var ilGenerator = dynamicMethod.GetILGenerator(); /*We use MS Intermediate Language calls to load the required information*/ ilGenerator.Emit(OpCodes.Ldstr, "Test Dynamic Method"); ilGenerator.Emit(OpCodes.Call, methodInfo); ilGenerator.Emit(OpCodes.Ret);//Return statement //We can create dynamic delegates and execute our method var action = (Action)dynamicMethod.CreateDelegate(typeof(Action)); action();//Prints in Debug Console //This statement verifies that the action was created at runtime Assert.AreEqual(action.GetType(), typeof(Action)); }
All Unit Tests are passing, you can modify the content of the tests in order to try different combinations or concepts.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4