8000 GitHub - MartinChavez/CSharp: C# : Test-Driven Learning
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

MartinChavez/CSharp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C# : Test-Driven Learning

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:

  • Fundamentals
  • Classes and Objects
  • Primitive Types
  • Types
  • Events
  • Access Modifiers
  • Arrays
  • Boxing
  • Exceptions
  • Loops
  • Methods
  • Operators
  • Value Types
  • Garbage Collection
  • Threads
  • Reflection
  • COM Interop
  • PInvoke
  • Generics

Tools

Basics

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();

Garbage Collection

        [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
        }

Generics

        [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));
            }

Run the Unit Tests

All Unit Tests are passing, you can modify the content of the tests in order to try different combinations or concepts.

Author

Martin Chavez

Continue Learning

About

C# : Test-Driven Learning

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages

0