No one can ever master a programming language (PL) by studying it only without looking into and comparing it with other ones. Modern application software often requires a variety of components written in different PLs. Most importantly, language itself is not important at all; at least not important when compared to the fundamental ideas on architectures, frameworks, the design of the PL. A competing programmer can always get the hang of any PLs quickly.
Consequently, I make a list of PLs I would study seriously in the future.
The following part is the first part of my series notes on the book Essential C#, which is redeemed as the best book for C# learners.
HelloWorld.exe is an assembly.
Dynamic Link Library (DLL) is also an assembly.
Language Contrast: Java—Filename Must Match Class Name
keywords, identifiers. keywords may be used as identifiers if they include “@” as a prefix.
method, statement
Language Contrast: C++/Java -- main()
is all lowercase
Strings are immutable.
composite formatting.
System.Console.WriteLine("Your full name is {0} {1}.", firstName, lastName);
// -------format string------- ----format item-----
/**comment**/
///comment
C# src --(C# compiler)--> common intermediate language(CIL) --(justintime compiling)--> machine code
Virtual Execution System(VES)
double
decimal
? append an m (or M): 1.32525456874526m
int
uint
, long
, ulong
.U
/L
/UL
/LU
E
\uxxxx
unicode char in hex, e.g. \u0029
@
)System.Text.StringBuilder
\r\n
\n
Console.WriteLine()
or Console.Write(Environment.NewLine);
void
is not
considered a data type* in the same way. Rather, it is used to identify that a
method does not return a value.var
introduced to support anonymous types, e.g. var patent1 = new { Title = "Bifocals", YearOfPublication = "1884" };
. Avoid to use in other cases.string
and object
, all derive from System.ValueType
string
, object
, any custom classes, most classesint? count = null;
Parse(T1 to, T2 from)
System.Convert
bool TryParse(T1 to,T2 from, T1 number)
Arrays
string[] languages;
square brackets identify the rank (# of dimensions)int numbers[]
is not allowed.string[] languages = { "C#", "COBOL", "Java" };
string[] languages; languages = new string[]{"C#", "COBOL", "JAVA" };
new string[size];
Assigning
int[,,,]
int[][][]
Using
Sort()
, BinarySearch()
, Reverse()
, Clear()
, ...System.Array.Resize()
.ToCharArray()
// instantiating
int[,] cells = {
{1, 0, 2},
{0, 2, 0},
{1, 2, 1}
};
int[][] cells = {
new int[]{1, 0, 2},
new int[]{0, 2, 0},
new int[]{1, 2, 1}
};
// handle conversion overflow with checked and unchecked
checked {
}
unchecked {
}
Increment()
and Decrement()
in System.Threading.Interlocked
class??
) evaluates an expression for null and returns a second expression if the value is null.foreach (type variable in collection) { /* do something */ }
variable
is read-only, and its scope is limited to the foreach loop
switch
statement to fall through from one case
block to the next if the case
includes a statement. A jump statement is always required following the statement within a case.// Null Coalescing Operator
string fileName;
// ...
string fullName = fileName??"default.txt";
// ...
// Preprocessor Directives
#if CSHARP2
System.Console.Clear();
#endif
#if LINUX
...
#elif WINDOWS
...
#endif
// you can define a preprocessor symbol in two way
// first,
#define CSHARP2
// second, in CLI
// >csc.exe /define:CSHARP2 TicTacToe.cs
#warning "Some move allowed multiple times."
// Performing main compilation...
// ...\tictactoe.cs(471,16): warning CS1030: #warning: ’"Same move allowed
// multiple times."’
// Build complete -- 0 errors, 1 warnings
// Note that warning numbers are prefixed with the letters CS in the compiler output.
// to disable warnings, first,
#pragma warning disable 1030
// second,
// > csc /doc:generate.xml /nowarn:1591 /out:generate.exe Program.cs
#pragma warning restore 1030
// one of the most common warnings to disable is CS1591, as this appears when you elect to
// generate XML documentation using the /doc compiler option, but you neglect to document
// all of the public items within your program.
// specify line numbers
#line 113 "TicTacToe.cs"
#warning "Same move allowed multiple times."
#line defualt
// display line 113 and then restore
// for visual editors to open/collapse
#region Display Tic-tac-toe Board
...
#endregion Display Tic-tac-toe Board
import
directive, while C# requires each namespace to be imported explicitly.using
could be nested in other namespaces but seldom used in this way.using CountDownTimer = System.Timers.Timer;
static int Main(string[] args)
By convention, a return other than zero indicates an error.args[0]
. The name of the program is omitted. args
or System.Environment.GetCommandLineArgs()
Main()
Methods in a program? use >csc.exe /m main.cs
string
as parameters are passed by valueref
)ref Type variable
in the function's list of args and call it with ref variable
out
)params
)try { } catch { }
Language Contrast C++: try { } catch (...) { }
. JAVA: Exception
is the base class for all exceptions, so try { } catch (Exception e) { }
.bool int.TryParse(textVariable, out number)
// Aliasing a namespace or type
using Timer = System.Timers.Timer;
class HelloWorld
{
static void Main()
{
Timer timer;
// ...
}
}
// Refrence Parameters
class Program
{
static void Main() {
string first = "first";
string second = "second";
Swap(ref first, ref second);
System.Console.WriteLine(@"first = ""{0}"", second = ""{1}""", first, second);
}
static void Swap(ref string first, ref string second) {
string tmp = first;
first = second;
second = tmp;
}
}
// Parameter Arrays
class PathEx
{
static void Main()
{
string fullName;
fullName = Combine(
Directory.GetCurrentDirectory();
"bin", "config", "index.html");
Console.WriteLine(fullName);
fullName = Combine(
Environment.SystemDirectory,
"Temp", "index.html");
Console.WriteLine(fullName);
fullName = Combine(
new string[] {
"C:\", "Data",
"HomeDir", "index.html"} );
Console.WriteLine(fullName);
}
static string Combine(params string[] paths)
{
string result = string.Empty;
foreach (string path in paths) {
result = System.IO.Path.Combine(result, path);
}
return result;
}
}
// named arguments
class Program
{
static void Main()
{
DisplayGreeting(firstName: "Tim", lastName: "Pan");
}
public void DisplayGreeting(
string firstName,
string middleName = default(string),
string lastName = default(string))
{
// ...
}
}
public
, private
, protected
, internal
, protected internal
new
as a call to instantiate an object, not as a call to allocate memory. It just retrieves memory from the memory manager.FirstName
, then field name _FirstName
(preferred), _firstName
, or m_FirstName
(C++ style).private set()
ref
or out
Parameter ValuesEmployee emp1 = new Employee("Inigo", "Montoya") { Title = "Computer Nerd", Salary = "Not Enough"};
this
public Employee(int id, string fristName, string lastName): this(firstName, lastName) { Id = id ; }
const
fields are static
automatically, and declaring a const
field as static
explicitly will cause a compile errorreadonly
modifier is available only for fields (not for local variables) it is modifiable only from inside the constructor or directly during declaration. 似乎是把C++中const
可以ctor初始化的功能拆成readonly
了.partial
Classespartial
methods allow for a declaration of a method without requiring
an implementation. However, when the optional implementation is
included, it can be located in one of the sister partial class definitions,
likely in a separate file.sealed
class cannot be derived. Language Contrast: C# sealed class = Java final class. In java, final
can be applied tovirtual
, and in a derived class this can be prevented for further classes with sealed
again.virtual
and override
keywords.new
modifier for methods. If neither override
nor new
is specified, then new
will be assumed, thereby maintaining the desired version safety.public Contact(string name) : base(name) { Name = name; }
=0
. It does not require the class itself to have any special declaration.abstract
if the class has abstract
memberSystem.Object
System.Object
is
operatoris
operator, e.g. if (data is string) data = Encrypt((string) data);
as
operatorPrint(data as Document);
// C++ Dispatch method calls during construction
// It will call method in the same class although it is virtual
#include <iostream>
using namespace std;
class A {
public:
A() {
cout << "A ctor()" <<endl;
Foo();
}
virtual void Foo() {
cout << "A Foo()" <<endl;
}
};
class B: public A {
public:
B() {
cout << "B ctor()" << endl;
Foo();
}
void Foo() {
cout << "B Foo()" << endl;
}
};
class C: public B {
public:
C() {
cout << "C ctor" << endl;
Foo();
}
void Foo() {
cout << "C Foo()" << endl;
}
};
int main(int argc, char** args) {
A* a = new C();
delete a;
return 0;
}
// output>
// A ctor()
// A Foo()
// B ctor()
// B Foo()
// C ctor
// C Foo()
// C#
using System;
class Tmp {
static int Main(string[] args) {
A a = new C();
return 0;
}
}
class A {
public A() {
Console.WriteLine("A ctor");
Foo();
}
public virtual void Foo() {
Console.WriteLine("A Foo()");
}
}
class B: A {
public B() {
Console.WriteLine("B ctor");
Foo();
}
public override void Foo() {
Console.WriteLine("B Foo()");
}
}
class C: B {
public C() {
Console.WriteLine("C ctor");
Foo();
}
public override void Foo() {
Console.WriteLine("C Foo()");
}
}
// output>
// A ctor
// C Foo()
// B ctor
// C Foo()
// C ctor
// C Foo()
// upcasting in C#
// `new` modifier for methods
using System;
class Tmp {
static int Main(string[] args) {
D1 d1 = new D1();
D2 d2 = new D2();
C c = d1;
B b = c;
A a = b;
d1.Foo();
d2.Foo();
c.Foo();
b.Foo();
a.Foo();
return 0;
}
}
class A {
public void Foo() {
Console.WriteLine("A Foo()");
}
}
class B: A {
public new virtual void Foo() { // warning if without new
Console.WriteLine("B Foo()");
}
}
class C: B {
public override void Foo() {
Console.WriteLine("C Foo()");
}
}
class D1: C {
public new void Foo() {
Console.WriteLine("D1 Foo()");
}
}
class D2: C {
public void Foo() { // warning to add `new` by default
Console.WriteLine("D2 Foo()");
}
}
// D1 Foo()
// D2 Foo()
// C Foo()
// C Foo()
// A Foo()
// upcasting in C++
// A -> B -> C -> D
// A::Foo()
// virtual B::Foo()
// virtual C::Foo()
// D:Foo()
// ...
int main(int argc, char** argv) {
D* d = new D();
C* c = d;
B* b = c;
A* a = b;
d->Foo();
c->Foo();
b->Foo();
a->Foo();
delete d;
return 0;
}
//
// D Foo()
// D Foo()
// D Foo()
// A Foo()
IPascalCase
, no implementation, no data (no fields, but properties)- Declaring a class to implement an interface is similar to deriving from a
base class in that the implemented interfaces appear in a comma-separated
list along with the base class (order is not significant between interfaces).
***The only difference is that classes can implement multiple interfaces.***
- The base class specifier (if there is one) must come first: `public class Contact : PdaItem, IListable, IComparable {...`
- ***Explicit(more often) vs Implicit*** [Stackoverflow](http://stackoverflow.com/questions/143405/c-sharp-interfaces-implicit-implementation-versus-explicit-implementation) ??
- Explicit: mechanism code, or avoid overriding,
- `ITrace.Dump()` to save info to files in `Person`
- Implicit: semantic/model/core code
- Including an implicit `Compress()` implementation on a `ZipCompression`
class is a perfectly reasonable choice, since `Compress()` is a core
part of the `ZipCompression` class’s behavior.
Base b = new Derived()
)// Explicit interface implementation
public class Contact : PdaItem, IListable, IComprarable
{
// ...
string[] IListable.ColumnValues
{
// ...
}
// ...
}
// ...
values = ((IListable)contact2).ColumnValues;
// ...
All the C# primitive types are value types except string
and object
. How to define user's own value types? struct
System.Object
-> System.ValueType
)struct
fields can not be initialized at declaration time.class
, struct
does not support finalizers. There is no need for the GC.T default(T)
to get the default valueValueType
to Object
lock
statementint
(default), uint
, long
,
or ulong
, but not char
.System.Array
Enum.Parse()
[Flags]
FlagsAttribute to perform bit operations.