Source Code
Browse the .NET Framework source code online: https://referencesource.microsoft.com/
Debugging Using Coredumps / Process Dumps In Visual Studio
See these articles:
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-managed-code
https://docs.microsoft.com/en-us/dotnet/framework/tools/sos-dll-sos-debugging-extension
Online C# Interpreters
Try these websites to test code if you don’t want a full dev environment
Visual Studio
In VS type “ctor” and press TAB twice to automatically generate the constructor code for a class.
"propfull" will autogenerate the setter/getter code for a property.
To comment code out, highlight code, press control-k, control-c (there is also a button to do this)
You can start typing the name of an object and press TAB for VS to auto-complete it.
When implementing the methods/properties of an interface in a subclass, hover over the interface name and the VS lightbulb will show up. Select "Implement Interface" and VS will autofill the code for those methods/properties
In VS's C# Interactive window, you can type "#r <class dll to load>" to load one of your classes' DLL. You can then invoke your methods directly
Control-. will automatically add "using <namespace>" for a class that is missing its using line.
Use three slashes (///) on top of a method/class and VS will create XML comments for their APIs
C# Documentation
Constructors
You can chain constructors by using "this ()".
public class Roger { // Default constructor public Roger() { } public Roger (string arg) : this () { }
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 nameof
expression
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.
PropertyCollection
Represents a collection of properties that can be added to DataColumn, DataSet, 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:
A search of open-source code where this object is used: https://csharp.hotexamples.com/examples/System.DirectoryServices/PropertyCollection/-/php-propertycollection-class-examples.html
Print the name and value of each item in a collection: https://stackoverflow.com/questions/640792/how-do-i-loop-through-a-propertycollection
What are the differences between a PropertyCollection and a Dictionary?
A PropertyCollection is derived from a HashTable as shown in the source code: https://referencesource.microsoft.com/#system.data/system/data/PropertyCollection.cs,21
You can see the differences between hashtables and dictionaries here: Difference between Hashtable and Dictionary in C#
Other sources:
This is in an Excel VBA reply but it may be applicable since the libraries are usually the same: How a Dictionary Differs from a Collection
https://stackoverflow.com/questions/32479842/comparison-of-dictionary-collections-and-arrays
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.
Add Comment