DLL vs EXE Link to heading

Dynamic Linked Library, cannot run individually. Executable file have Main function.

Naming Conventions Link to heading

Object NameNotationLengthPluralPrefixSuffixAbbreviationChar MaskUnderscores
Class namePascalCase128NoNoYesNo[A-z][0-9]No
Constructor namePascalCase128NoNoYesNo[A-z][0-9]No
Method namePascalCase128YesNoNoNo[A-z][0-9]No
Method argumentscamelCase128YesNoNoYes[A-z][0-9]No
Local variablescamelCase50YesNoNoYes[A-z][0-9]No
Constants namePascalCase50NoNoNoNo[A-z][0-9]No
Field namecamelCase50YesNoNoYes[A-z][0-9]Yes
Properties namePascalCase50YesNoNoYes[A-z][0-9]No
Delegate namePascalCase128NoNoYesYes[A-z]No
Enum type namePascalCase128YesNoNoNo[A-z]No

fields vs properties Link to heading

properties exposes fields. meaning properties have getter and setter whereas fields store actual data.


...
// this is a field
private string _myField;

// this is a property
public string MyProperties
{
  get => _myField;
  set => _myField = value;
}
...

Numbers Link to heading

int can be overflowed

class Link to heading

  • class modifier: sealed, abstract

  • Class inheritance: only directly inherit one base class that is not defined as sealed

    sealed modifier prevents other classes from inheriting from it.

    abstract is intended only to be a base class of other classes.

    members marked as abstract must be implemented by classes that derive from the abstract class.

  • The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time.

  • C# is both passing by value and reference

    if the intent is passing by reference, using keyword ref and out

  • using The reason for the using statement is to ensure that the object is disposed as soon as it goes out of scope, and it doesn’t require explicit code to ensure that this happens.

class vs. struct Link to heading

almost the same, it is recommended that group small data using struct, however, struct can also have methods, properties, fields, constructor, in that case, class is recommended being used.

Square Brackets Link to heading

  • array access, like name[0]
  • indexer (mainly used for dictionary I guess), like dict[“idx”];
  • square brackets in front of classes called Attribute, which is a counterpart of Java annotations, but with differences like assembly level attributes and stuff.

pointers Link to heading

C sharp allows pointers.

use unsafe keyword to allow pointers in code blocks.

unsafe keyword can be used in methods, members.

Exceptions Link to heading

unlike Java, in C# people cannot throw exceptions in signatures.

just throw exceptions inside code block.

Inheritance Link to heading

: Link to heading

class Child : Parent

meaning class called Child is derived from class called Parent, and Parent is the base class of Child

base keyword Link to heading

base class does not have to be an abstract class, it can be a real class.

It is an error to use the base keyword from within a static method.(reason: for static method, there is no current instance. when calls base, it will ask for the base instance of derived instance, conflicted).

override keyword (both inheritance and polymorphism) Link to heading

The overridden base method must be virtual, abstract, or override

Polymorphism(C# polymorphism is more flexiable than java) Link to heading

initiate an instance of Interface

接口不能实例化!但是如果非要 实现接口的类 实例 = new 实现接口的类() 那要接口有什么用?

接口 实例 = new 实现接口的类A()

接口 实例 = new 实现接口的类B()

接口 实例 = new 实现接口的类C()

We can create a new Class D that implements this Interface to encapsulate method ABC. This is the Factory Mode

Encapsulation Link to heading

Access Modifier

  • public: access is not restricted
  • protected: Access is limited to the containing class or types derived from the containing class. (in other words, this class and/or subclass)
  • internal: (seems like protected internal is more valuable)
  • private: Access is limited to the containing type

“::” Link to heading

called The namespace alias qualifier

“?” after a type Link to heading

meaning the value of type is nullable.

Nullable types are declared in one of two ways:

System.Nullable<T> variable

-or-

T? variable

“??” or null coalescing operator Link to heading

string Answer = Answer1 ?? Answer2;

Translation in English is that “if whatever in left is NOT null, use that, otherwise, use what is to the right”.

“@” before a string Link to heading

It means to interpret the string literally (that is, you cannot escape any characters within the string if you use the @ prefix)

Generics in C# Link to heading

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T input) { }
}
class TestGenericList
{
    private class ExampleClass { }
    static void Main()
    {
        // Declare a list of type int.
        GenericList<int> list1 = new GenericList<int>();
        list1.Add(1);

        // Declare a list of type string.
        GenericList<string> list2 = new GenericList<string>();
        list2.Add("");

        // Declare a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
        list3.Add(new ExampleClass());
    }
}

The most common use of generics is to create collection classes

You can create your own generic interfaces, classes, methods, events and delegates

more advanced about generic classes, firstly know some concepts: concrete type, closed constructed type, open constructed type

Generic classes can inherit from concrete, closed constructed, or open constructed base classes:

class BaseNode { }
class BaseNodeGeneric<T> { }

// concrete type
class NodeConcrete<T> : BaseNode { }

//closed constructed type
class NodeClosed<T> : BaseNodeGeneric<int> { }

//open constructed type 
class NodeOpen<T> : BaseNodeGeneric<T> { }

Non-generic classes can only inherit concrete or closed structured base classes.

//No error
class Node1 : BaseNodeGeneric<int> { }

//Generates an error
//class Node2 : BaseNodeGeneric<T> {}

//Generates an error
//class Node3 : T {}

Generic classes can also do some I-call-it smart mapping

class BaseNodeMultiple<T, U> { }

//No error
class Node4<T> : BaseNodeMultiple<T, int> { }

//No error
class Node5<T, U> : BaseNodeMultiple<T, U> { }

//Generates an error
//class Node6<T> : BaseNodeMultiple<T, U> {}

Generic classes that inherit from open constructed types must specify constraints that are a superset of, or imply, the constraints on the base type:

// constraints on T
class NodeItem<T> where T : System.IComparable<T>, new() { }
class SpecialNodeItem<T> : NodeItem<T> where T : System.IComparable<T>, new() { }
...
class SuperKeyType<K, V, U>
    where U : System.IComparable<U>
    where V : new()
{ }

Interfaces Link to heading

By convention, interface names begin with a capital I.

interface IEquatable<T>
{
    bool Equals(T obj);
}

To implement an interface member, the corresponding member of the implementing class must be public, non-static, and have the same name and signature as the interface member.

Any class implements interface IEquatable<T> must provide an implementation of Equal method.

Example:

public class Car : IEquatable<Car>
{
    public string Make {get; set;}
    public string Model { get; set; }
    public string Year { get; set; }

    // Implementation of IEquatable<T> interface
    public bool Equals(Car car)
    {
        return this.Make == car.Make &&
               this.Model == car.Model &&
               this.Year == car.Year;
    }
}

events and delegates Link to heading

we’d like to be able to pass it to somebody else so that they can call it. This is especially useful in an event-driven system such as a graphical user interface, when I want some code to be executed when the user clicks on a button, or when I want to log some information but can’t specify how it is logged.

The signature of a single cast delegate is shown below:

delegate result-type identifier ([parameters]);

Examples:

public delegate void SimpleDelegate ()

This declaration defines a delegate named SimpleDelegate, which will encapsulate any method that takes no parameters and returns no value.

public delegate int ButtonClickHandler (object obj1, object obj2)

This declaration defines a delegate named ButtonClickHandler, which will encapsulate any method that takes two objects as parameters and returns an int.

Let’s see a more advanced example

using System;
using System.IO;

namespace Akadia.SimpleDelegate
{
    // Delegate Specification
    public class MyClass
    {
        // Declare a delegate that takes a single string parameter
        // and has no return type.
        public delegate void LogHandler(string message);

        // The use of the delegate is just like calling a function directly,
        // though we need to add a check to see if the delegate is null
        // (that is, not pointing to a function) before calling the function.
        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler ("Process() end");
            }
        }
    }

    // The FileLogger class merely encapsulates the file I/O
    public class FileLogger
    {
        FileStream fileStream;
        StreamWriter streamWriter;

        // Constructor
        public FileLogger(string filename)
        {
            fileStream = new FileStream(filename, FileMode.Create);
            streamWriter = new StreamWriter(fileStream);
        }

        // Member Function which is used in the Delegate
        public void Logger(string s)
        {
            streamWriter.WriteLine(s);
        }

        public void Close()
        {
            streamWriter.Close();
            fileStream.Close();
        }
    }

    // Test Application which calls both Delegates
    public class TestApplication
    {
         // Static Function which is used in the Delegate
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }

        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("process.log");

            MyClass myClass = new MyClass();

            // Crate an instance of the delegates, pointing to the static
            // Logger() function defined in the TestApplication class and
            // then to member function on the fl instance of a FileLogger.
            MyClass.LogHandler myLogger = null;
            myLogger += new MyClass.LogHandler(Logger);
            myLogger += new MyClass.LogHandler(fl.Logger);

            myClass.Process(myLogger);
            fl.Close();
        }
    }
}

Compile an test:

# csc SimpleDelegate4.cs
# SimpleDelegate4.exe
Process() begin
Process() end
# cat process.log
Process() begin
Process() end

This is called multicasting. Being able to point to member functions is nice, but there are more tricks you can do with delegates. In C#, delegates are multicast, which means that they can point to more than one function at a time (that is, they’re based off the System.MulticastDelegate type).

Data Structures in C# Link to heading

  • ArrayList: a dynamic array. Usage: ArrayList myArrayList = new ArrayList(); ArrayList doesn’t implicit any type, so accept different objects.

  • List<T>: single type elements ArrayList

  • LinkedList<T>: DOUBLY linked list. Cool! and also I can grab LinkedListNode<T> using either First or Last

  • Stack<T>: Push(), Pop(), Peek()

  • Queue<T>: Contains(), Enqueue(), Dequeue(), Peek()

  • HashSet<T>: bool Add(), bool Contains(), IntersectWith(), Remove()

  • Dictionary<TKey, TValue>: C#’s Dictionary uses [] indexing for setting/getting items

    myDictionary[key] = value;
    bool TryGetValue();
    

LINQ Link to heading

  • Lamda (Method) Syntax

    var longWords = words.Where( w  w.length > 10);
    Dim longWords = words.Where(Function(w) w.length > 10)
    
  • Query (Comprehension) Syntax

    var longwords = from w in words where w.length > 10;
    Dim longwords = from w in words where w.length > 10
    

LINQ to SQL (DLINQ)

Unit Tests Link to heading

Here take Nunit as example.

I found cannot using namespace right away, that is because I don’t reference.

  1. Add a Reference to Your Project

    In order to test the code in your main project, you need to add a reference to it in your test project.

    • Right click on your test project
    • Click on Add | Reference
    • Select Projects | Solution
    • Add a checkmark on your main project.
    • Click OK.
  2. open the Test Explorer Window.

    To do this, in the main menu, click Test | Windows | Test Explorer.

  3. Click Run All to run your tests

Mock (Moq) Link to heading

moq documentations