C# Notes And Tips


Source Code

 

Browse the .NET Framework source code online: https://referencesource.microsoft.com/

 


Sample Code

 


Debugging Using Coredumps / Process Dumps In Visual Studio

 

See these articles:

 


Online C# Interpreters

 

Try these websites to test code if you don’t want a full dev environment

 


C# Documentation

C# documentation


Methods

  • Static methods are methods you can call without instantiating the class.  Eg Math.Abs()

  • Function-bodied expressions allow for quick one-liner expressions:  func() => expression

  • You can override methods from the base class by adding the override qualifier to your function.

 


Classes

  • A C# class defines (encapsulates) an object

  • If you want a base class not to be instantiated by others, add the modifier “abstract class”

  • To inherit from another (base) class, follow the class name with a colon and the base class name:  e.g. "class myclass : <base class name>"

    • You can only inherit from one class.  See Interfaces for more options.

  • You can define an abstract method in a base class (a function with no code, e.g. pubic abstract float computePrice(); ) that you can then provide different implementations in all the subclasses that inherit the base class.  Note that all classes must implement the abstracted method.   In the inheriting class, you must use the override qualifier for the abstracted method.

    • If you don't want to have to implement a method in each subclass that inherits the base class, then declare the base method as virtual.




Interfaces

  • By convention, names of interfaces begin with the capital letter "I"

  • As opposed to base classes, a class can inherit from multiple interface classes ( class myclass : <Iinterface1>, <Iinterface2>).  An interface can be shared by multiple classes

  • Interfaces describe common behavior and not a specific object.

  • Interfaces don't have any code logic in them.  It is just a prototype (empty methods).  The class itself must provide the code for that interface.  It can also hold its own properties, just like a class but the actual get/set implementation must be implemented in the class (just like the methods).  You can't declare member variables but properties can get around that.

  • Interfaces don't need to have modifiers since all members are inherently public. 

  • Interfaces can't be instantiated (ie foo = new interface ABC).

  • Multiple interfaces inherited by a class can have the same method names in them.  In the class, you need to prepend the method names with the interface names in order to differentiate them (e.g. void IStorable1.commonMethodName()).  If you don't, the class method will be used as the method for all interited interfaces.

  • You can use the "is" operator to test if a class inherits from an interface. (e.g.  if (myclass is IStorable) )

  • You can also cast a class which inherits an interface "as" that interface (e.g. IStorable obj = myclass as IStorable). If the cast doesn't succeed, it will set the obj to null.




Nameof

 

If you want to log the name of a parameter/variable, rather than textually putting the name in the message, use the nameofexpression

Examples from: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/nameof

var numbers = new List<int> { 1, 2, 3 }; Console.WriteLine(nameof(numbers)); // output: numbers Console.WriteLine(nameof(numbers.Count)); // output: Count Console.WriteLine(nameof(numbers.Add)); // output: Add

You can use a nameof expression to make the argument-checking code more maintainable:

public string Name { get => name; set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null"); }

 

More common uses for nameof operator can be found here:


IDisposable Interface

 

  • The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.

    Use the Dispose method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector.

  • Classes that deal with garbage disposing elements implement the "IDisposable" interface.  Use the keyword using when invoking them.


Logging

  • Search in NuGet.org for a logging package such as NLog.


JSON Serialization

See:


PropertyCollection 


Represents a collection of properties that can be added to DataColumnDataSet, or DataTable

//Get a PropertyCollection. PropertyCollection properties = new PropertyCollection(); //Add a timestamp value to the PropertyCollection. properties.Add("TimeStamp", DateTime.Now); // Print the timestamp. Console.WriteLine(properties["TimeStamp"]);

Examples:

What are the differences between a PropertyCollection and a Dictionary?

 

 

Other sources:


Generics

  • Add type safety and reusability when handling collections (most common case)

  • Gives you a way to tell the C# compiler what type of data you intend to use with a given class, without the class needing to know about that type.

  • Generics give you better performance than their counterparts because it avoids the C# boxing and unboxing of objects stored in the non-generic lists/arrays.

  • The data type of the objects held by the data structures is specified in angle brackets (e.g. List<int> myList = new List<int>() )

  • System.Collections.Generic Namespace documentation.






Secure Coding Guidelines