RoutedEventArgs – basics

http://msdn.microsoft.com/en-us/library/system.windows.routedeventargs.aspx

The 4 properties of RoutedEventArgs are key. You may want to compare with the PropertyChangeEvent in swing…

– Halted property – writable
– OriginalSource is usually less useful than Source
– RoutedEvent … is the actual event?

In Silverlight, only OriginalSource is available 😦

Advertisements

dotnet unmanaged RESOURCES, learning notes

(Many open questions below are a bit arcane and may not be relevant to IV or projects.)

I feel “managed” means “automatically-released”. In that case, most dotnet Objects qualify as managed “Resources”. Any time you need Dispose() in your CLASS, that’s a telltale sign of unmanaged resources.

“Resource” is a rather abstract term, best understood by example[1]. In my mind, a resource is some runtime object(s) needed by our App, something constructed and configured. Like a natural resource it is scarce, shared and rationed. Like a library book, there’s usually an acquisition “protocol”, and a return protocol.

[1] As a crude example, what’s a city and what’s not a city? Best learn by example.

http://stackoverflow.com/questions/13786570/determine-managed-vs-unmanaged-resources has some interesting comments.

–Unmanaged resource and … IntPtr + handle ?
What’s an IntPtr? Basically a struct that represents a native void pointer (or a native handle) —
http://stackoverflow.com/questions/1148177/just-what-is-an-intptr-exactly Many unmanaged “resources” are accessed via IntPtr.

–Unmanaged resource and unsafe code?

–Unmanaged resoruce and p/invoke?

–Unmanaged resource and … win32 + COM?

–some managed resources
filestream is a MR. It contains a native file handle, which is UR. It’s IntPtr, but not a integer-based file descriptor as in C/python. See MSDN.

A socket object is a MR. It contains a socket handle, which is UR and IntPtr

A DB connection is probably UR.

who generates the local proxy for the remote

In any distributed-OO infrastructure (ejb, rmi, wcf, remoting…), someone needs to generate a proxy class based on the server-side
API. If you aren’t paying attention, you will not notice where, when and how exactly this is generated. But this is a crucial detail
not to be missed.

There’s a bit of ambiguity over 2 related concepts — Instantiating a proxy instance (at run-time) vs Generating a proxy class
source code before compiling.

(I like to say “client-side proxy” but the adjective is superfluous. )

— WCF —
Usually i generate the “service reference” from a wsdl or the service endpoint URL.

2 frontiers between swing/OS

Between the swing layer and OS layer, there are 2 interactions “channels”. In other words, swing relies on 2 services provided by
the “hotel service desk” that’s the OS.

A: upward -> screen update, targetting a particular screen object
B: downward -> keyboard/mouse events when user interacts with a screen object

In both domains, data/events are bound to individual screen/visual objects. Eech screen object maps to one (or more) swing object + one (or more) native object “protected” by the OS. Remember OS is the wrapper layer on top of hardware, and all access to hardware must go through the OS.

You encounter low-level details when digging into either of the 2 domains
A: painting, java 2D, UI delegates
B: event pumping, low-level vs semantic events.

suggest(hint) a GC run – CLR ^ JVM

Java’s gc() method is a suggestion/plea to JVM at run-time. (There’s no way to force an immediate GC cycle. I often call gc() some 4000 times in a few loops to coax the GC to start.)

CLR Collect() method with Optimized mode is exactly the same.

CLR Collect() method with Forced mode would force an immediate collection. No such feature in JVM.

All of these techniques are discouraged. When are they justified?

OneWayToSource, briefly

Logically, there are 2 sides to a (logical) binding — Source property and Target property. Both must be properties (not fields) of some class. Target must be a dependency property, not a plain property.

Behind the scene, there is a Binding object, with a Source field (not to be confused with the “source” property) and a Path field (Better rename to “PropertyNameInSourceObject”). You inject Binding object into the Target visual control. Once injected, the target visual is wired up to the source property, via the binding.

I feel target is usually a visual. Source property often isn’t a visual — it could be a plain property in a POCO object. When source property gets edited, WPF engine would somehow update the visual. That’s the plain vanilla OneWay update mode.

When used as a Target visual, some visuals default to 2-way update, like TextBox. Other visuals default to one-way update i.e. source to target.

OneWayToSource is a special mode. One reason you may need it — when exactly one of the 2 sides is a dependency property. By WPF policy that side must be the Target, whereas the non-dependency side will be Source. If you need to update the non-dependency side, you can use OneWayToSource. Imagine the non-dependency side could be a POCO object with a plain property, but you need to update it when the textbox gets edits. In summary, system automatically updates the non-dependency property from a visual control on screen.

When both source Obj and target Obj are visuals, we can often make do without data binding — use event instead.

c# bbg IV – 15minutes

Q: Can a struct implement an interface
%%A: an interface is a reference type. When casting to the interface type, you get autoboxing
A: http://stackoverflow.com/questions/63671/is-it-safe-for-structs-to-implement-interfaces shows many standard structs implement
IEquatable and other interfaces

Q1 When I create a custom class, what’s the type I derive from?
%%A: System.Object, which is a reference type

Q1b What methods do you usually override in your custom class
%%A: tostring, gethashcode, equals. Fairly good answer.

Q: what are the value types you normally create
%%A: enums and structs

Q: what’s IDisposable

Q: what’s the relationship – IDisposable vs Finalizer

Q: Mutex vs Monitor

dotnet remoting and related jargon

P4 [[.net 1.1 remoting, reflection and threading]] shows a insightful history leading to dotnet remoting —
#1) RPC (pre-OO).
OO movement brought about the Next generation in the form of distributed objects (aka distributed components) —
#2) CORBA, RMI (later ejb) and dcom, which emerged around the same time.
COM is mostly for in-process and dcom is distributed
#3) soap and web services , which are OO-agnostic
I feel soap is more like RPC… The 2 distinct features of soap — xml/http. All predecessors are based on binary protocols (efficient), and the “service component” is often not hosted in any server.
#4) dotnet remoting feels more like RMI to me…According to the book above, remoting can use either
1) http channel with the soap formatter, or
2) tcp channel  with the binary formatter

Therefore, I feel remoting is an umbrella technology with different implementations for different usage scenarios.

#5) WCF
Remoting vs wcf? See other post.

atomic operations offered in c++11 ^ pthreads libraries

P341 [[c++ concurrency in action]] has a nice table showing about 7 to 10 most important concurrency features across pthreads vs c++11 [2]. It’s obvious to me the 2 fundamental[1] and universally important features are locks and condVars. These are thoroughly and adequately supported everywhere — pthreads, c++11, java, c#. Beyond these 2 features, other features aren’t universally supported across the board. Let’s look at some of them.

— Atomic operations —
pthreads? no support
c++11? yes atomic types
java? yes atomic variables
boost? no support
c#? yes interlocked

Notice in the C#, c++11, java thread libraries there are specific constructs (classes and methods) for atomic INT and atomic BOOLEAN (but not atomic float), because in practice most atomic algorithms use primitive int and boolean types.

Atomic operations don’t always rely on specific CPU instructions. They are often “offered” on (no more than a few) specific atomic data types. Can we apply atomic operations on a random data type, like some method in a regular class? I doubt it. I feel in each thread library, there are no more than a few specific atomic Operations, tied to a handful of atomic data types.

— thread pool —
java? yes
c#? yes
c++11? no
pthreads? no
boost? To my surprise, No, according to the maintainer of boost::thread

I think it’s technically very feasible to implement thread pool using locks and condVars, so this feature is left out of the c/c++ base libraries.

[1] “Fundamental” is a imprecise term that I would not spend too much time debating. In c#, locks and condVars aren’t really rock-bottom fundamental. They are based on more fundamental constructs namely primitive kernel objects. In other languages, I’m not sure. Locks and condVars are often implemented in thread libraries not syscalls. It’s a bit obscure, arcane and even irrelevant to many developers.
[2] (and java and boost too, but this blog is about c++)

probability ^ statistics, hearsay

http://www.cs.sunysb.edu/~skiena/jaialai/excerpts/node12.html points out that

* P is about future; S is about past. Same as Chen Wei’s view. (Pudong development bank)
** Here’s a longer version. Both try to estimate the frequency of some event happening. P tries to predict the exact likelihood; S analyzes historical data to compute the frequency.
* P is theoretical; S is applied math dealing with real data
** P deals with an idealized world; S deals with real world data — often biased.
** [1] I believe if the real world data volume is very large and unbiased (like throwing thousands of coins many times) then the statistical conclusions should match the probability theory.

http://www.shodor.org/interactivate/discussions/ProbabilityVsStatis/ points out

– Statistics deals with data that may or may not be useful for finding probability. See my comments in [1].
– Statistics data can also be useful by itself, without any connection to probability.

Given the stringent requirement of probability, most stats data isn’t useful. But beyond probability, everyday a lot of these data are consumed and used to make important decisions.

y Dispose should call SuppressFinalize(this)

See [[accelerated c# 2010]]. Even more details are in [[.net gotchas]].

* small optimization idiom. I think it’s a sign of mastery, esp. if you can explain why.
* by default, if the class has a finalizer, then after Dispose, the object is still be seen with a finalizer. Will be moved to finalize queue. Delayed deallocation
* Often Dispose() handles all clean-up. In that case the final final finalization isn’t required any more.

Note GC.SuppressFinalize is a static method

deep clone in c# _ c++ _ java — briefly

A theoretical IV question — how is deep clone (aka deep copy) done?  Remember Each non-trivial object is an object graph.

reflection is a universal big-hammer. Covers private fields and covers all “embedded” base objects. However, usually the author of a given class should decide how to deep-clone her class, rather than using reflection.

deep-copy and serialization — Remember serialization needs to recreate entire graph on a remote machine. Deep copy required.

deep-copy and c++ big3 — A c++ class having a pointer field must be careful about big3. Deep-copy often required.

deep-copy and object equality — both may need to traverse the object graph.

java clone() method is controversial and isn’t widely used in all the projects I have seen. C# IClonable is also controversial. Stackoverflow mentions — Microsoft recommends against implementing ICloneable because there’s no clear indication from the interface whether your “Clone” method performs a “deep” or “shallow” clone.

Incidentally, stack overflow exception can happen during recursive object graph traversal, even if we take care of cycles.

replacement for stop/suspend/resume in java threads – intrusive?

c# Thread.Abort() is slightly better than java’s stop()…

—-
For suspend/resume, [[java thread programming]] P91 has a BestReplacement.java. However, I feel most designs don’t need suspend and resume. wait/notify is the standard replacement technique.

Nowadays, even wait/notify is seldom used by app developers. Nevertheless, BestReplacement.java presents some FUNDAMENTAL techniques or idioms. Do you ever need to go beyond the java5
concurrent utilities?

Some veterans point out that suspend/resume/stop are intrusive operations on a vm-thread via the thread handle. The non-intrusive alternatives are locks, conditions, interrupts and flow-control flags monitored by the “driver” methods (the method seeded in the thread). Most good designs use a combination of the above constructs to let the thread decide when to suspend/resume/stop itself. In contrast, the intrusive operations are unconditional, abrupt, unilateral actions on the thread by another thread.

c# lambda/closure executes when #again

The increment below is not executed when CLR executes Line #2 which sets up the thread. It’s executed only when the thread gets the “driver’s seat“, which doesn’t happen when Line #2 executes.

int x = 0; //#1
ThreadPool.QueueUserWorkItem(() => x++); //#2

The void lambda is more like a standalone method. This method is not executed when it seeds the new thread. It’s executed only when the thread runs.

More specifically, this lambda is more like a nameless closure —

Action myClosure = (() => x++);

CLR thread vs kernel/native thread data structures in memory

In the current CLR, each “CLR thread” maps to exactly one kernel/native thread after it start running. Before starting, it maps to

no kernel thread.

There's a kernel data structure for each running thread, including the stack. The dotnet CLR thread enriches that data structure

with additional info. One important additional info is the GC info. For each thread, CLR needs to know how to find local pointers to

heap objects. Unencumbered with this special GC requirement, the kernel doesn't have this additional data structure. See P86

[[concur programming on windows]]

include non-key columns in a non-clustered index to reduce IO counts

http://msdn.microsoft.com/en-us/library/ms190806.aspx shows this lesser known performance trick. If a query uses a particular NCI (non-clustered-index), and all the output fields are “included” on the index, then query won't hit the data pages at all.

How about sybase? http://dba.stackexchange.com/questions/15319/equivalent-of-include-clause-while-creating-non-clustered-index-in-sybase says not supported. But See also https://support.ca.com/cadocs/0/CA%20ERwin%20Data%20Modeler%20r9%201-ENU/Bookshelf_Files/HTML/ERwin%20Help/index.htm?toc.htm?define_sybase_table_index_properties.html

How many is too many threads in a process?

By default the dotnet thread pool has 250 threads per core[1]. In dotnet, I believe all threads are native, not “green” threads manufactured by the thread library.

I read in other places that 400 threads per core is considered a soft upper limit.

Remember each core, like a car, can only have one driver thread at any time. So all other threads must be inactive — blocked (i.e. context switched out, or preempted)

[1] My friend told me it’s just 25 in older versions.

c# DYNAMIC expando object (ExOb) – phrasebook

dynamic – better assign the exob instance to a dynamic variable. If you use a ExpandoObject variable, you lose a lot of features but i won’t elaborate …

javascript/python/perl – in these languages, a class instance is conceptually(?) and physically(?) a dictionary of name-value pairs. Exob is somewhat similar.

name-value pairs — In an exob instance, a field is (obviously) name-value pair. Ditto for a runtime-created method. The “value” is basically a (possibly void) lambda expression.

Emit — is the traditional technique to create a brand new class at run time and “emit” IL code into it. Exob is newer and simpler. I guess it’s more practical.

Finalize()/dtor ^ Dispose()

–some keywords
manual — Dispose() is NOT automatically invoked like Finalize(). Upper-layer programmers should but often forget to call it (Murphy’s law)
** defensive — better include a call to Dispose() in the dtor. Note dtor calling Dispose, not the other way round.

deterministic — Dispose(). You can control when it takes place. For serious resource management, use Dispose, since Finalize() may be pending for a long time on the finalizer thread.

Q: So what resource release should I put into Dispose()?
A: eg: window handlers (HWND), database connections… For these resources, Finalize() is another layer of defence. See P210 [[C# For Java Programmers]] for an HWND example.

–[[accellerated C# 2010]] has a concise coverage of the finalizer pitfall. Here are a few pointers.
Any class with a custom dtor must implement IDisposable, according to this book.

The finalizer thread calls Finalize() on each thread in the finalizer queue. Finalize() method is virtual but not overridable in c# (despite some confusing MSDN articles). Instead, you define a dtor like in c++, and Finalize() would invoke your dtor before all base dtors, just like c++.

See also http://stackoverflow.com/questions/1076965/in-c-sharp-what-is-the-difference-between-a-destructor-and-a-finalize-method-in

If you need to do anything in the dtor, it’s often better done in Dispose(). There is more than 1 reason to avoid custom dtor, so much so that I don’t see any good reason to ever do it.

spinlock, spinwait in c# — phrasebook

Smart spin — Both use smart spin. Traditionally, spin means hogging the driver’s seat unproductively, so other threads won’t get the time slices. Smart spin constructs don’t hog the driver’s seat for long.

lockfree — both contribute to lockfree algorithms, but
** Spinlock is unrelated to CAS.
** Spinwait doesn’t use CAS[1] but is often used with CAS

context switch — minimized. Both constructs minimizes context switch. The spinning thread doesn’t give up driver’s seat but spins briefly and then (hopefully) enters critical section.

optimistic — “brief” spin and retry

[1] according to my analysis. See MSDN
——-
Spinlock is comparable to a regular lock. A thread hitting a contended regular lock immediately, automatically gives up CPU (context switch). With a spinlock, the thread spins briefly if contended, then hopefully (optimist!) enters the critical section, without context switch. There are many differences but that’s the big picture.

c# REF parameter – pointer reseat

After using “ref” keyword for a while, I slowly realized it’s only useful if inside the method you reseat the pointer. Suppose the  caller of method m1() has a variable ovar and the object is at address 0x3. This is passed into m1 as parameter “pvar”.

If m1() reassigns to pvar, then you probably should use “ref” keyword
If m1() never reassigns to pvar, then you need not (and should NOT) use “ref” keyword

These are the guidelines for the common scenario, where pvar is class-type, so pvar is a pointer-VARIABLE (not a mere address; not a pointer-object). When pvar is reassigned, the behavior depends
** ref param? ovar is also reseated to a new address 0x7
** non-ref param? ovar is unaffected.

The much less common scenario is a struct-type method parameter. I feel most developers aren’t familiar, so better avoid it.
** ref, with assignment to pvar? ovar’s fields are completely overwritten and replaced. Note ovar still refers to (NOT “points to”) the object at 0x3.
** ref, with editing on pvar.field1? field1 of the object at 0x3 is modified.
** non-ref, with assignment to pvar? no effect on ovar, the change is local to the method
** non-ref, with editing on pvar.field1? ditto

finally{} should never throw

Principle EE — exception throwing during exceptional stack unwinding is often disastrous.

–c++
dtor should never throw, largely because of EE.

–java
finall{} should not throw. It often runs due to some exceptionA (i.e. exceptional stack unwinding as in EE). If finally block itself  throws excetionB, then exceptionA is simply hidden. As bad as dtor throwing.

–c#
same as java finally{}

Special case: Dispose() should not throw. Dispose() often runs in finally{} or in finalizer (on the finalizer thread)

http://msdn.microsoft.com/en-us/library/bb386039.aspx shows 10 other places not to throw!

"new virtual" modifiers in c#

Unlike java and c++, c# offers new-virtual, which marks a virtual method hiding a base-class virtual method.

* When used in an interface, you must omit the “virtual” since it’s implicit
* When used in a class C, you must spell out “new virtual”. There must be such a Virtual method in the base class B, and there should be a grand-child class D that Overrides this method. P75 [[c# precisely]] illustrates this BCD scenario.

In c#, “override” scares “new” as a method modifier, otherwise “new” plays happily with all other method modifiers —
– new virtual
– new abstract
– new static
– new (nothing) — simple, non-virtual method hiding

never edit table model on non-EDT?

A Swing interviewer asked me

Q: Can a non-EDT thread ever writes to the underlying data-structure of a (table/tree/list) model? 
A: If it does, we are at risk. EDT could be reading it — uncoordinated and unexpected. EDT might see corrupted data. Classic reader/writer race scenario. Murphy’s Law — if it could happen it will.

(In theory, EDT can also update the data due to a message listener or a DB operation –writer/writer race, but) This one scenario alone is reason enough. All underlying data queried by EDT should Never be modified outside EDT.

In one real world live trading app though, some MOM listener threads do indeed update underlying data structure. When that happens, users are not allowed to trigger a refresh — we can disable some buttons. After the update, we send invokeLater(fireXXX()) to refresh the view.

You may want to lock-protect the underlying data, but then EDT might be blocked. Yet, this is widespread. Look at DefaultTableModel in which EDT does access the underlying Vector, which is lock-protected. If the Vector is large, growing it (perhaps 2 folds) can take log(N) time, and EDT would be blocked for that duration. However, in practice this latency is probably below 50ms and unnoticeable.

As a minimum requirement, ALL models need to be thread-safe. That often entails locking or CAS or copy-on-write.

Swing models normally do not use large data structures (since a screen can’t realistically show even 1000 rows). If it does, update should ideally be designed with a worker thread, to populate a replacement data structure, and then ask EDT to swap it in. Many non-ideal situations exist in practice, which calls for specific techniques and tactical solutions.

c# Release^Debug build – cheatsheet

Update – to the compiler, there’s no Release/Debug mode. I think this is really a MSVS feature. (The optimization diff between R/D is, ironically, less important to me. ) Each “mode” specifies a set of compiler/linker flags (+ env var). As a result, each mode has its own output directory for the build artifacts — they don’t overwrite each other.

Optimized – Release build could be faster, usually marginal difference. YMMV i.e. actual improvement depends on many factors.

Local debug – Release won’t hit breakpoints. Can it be fixed? Online says maybe but I feel YMMV.

Remote debug – Both Release/Debug builds supported. See http://syncor.blogspot.com/2010/12/remote-debugging-release-build.html

There’s a lot of discussion and Q&A on this.
* For our knowledge, it’s more relevant to know (at least a few of) the many optimizations.
* For practical coding, better know the restrictions on Release builds

http://msdn.microsoft.com/en-us/library/wx0123s5.aspx says
* The Debug configuration of your program is compiled with full symbolic debug information and no optimization. Optimization complicates debugging, because the relationship between source code and generated instructions is more complex.

* The Release configuration of your program contains no symbolic debug information and is fully optimized. Debug information can be generated in Program Database Files (C++), depending on the compiler options that are used. Creating PDB files can be very useful if you later have to debug your release version.

–Forum authors point out
Size of the release executable is smaller than a debug executable. In terms of execution speed, a release executable will execute faster for sure, but not always will this difference be significant.

One can expect to see funny errors in release builds due to compiler optimizations or differences in memory layout or initialization. These are referred to as Release-Only bugs.

%% c# brain bench

Q: what modifiers are equivalent to static when defining a class? Perhaps a invalid question
Q: build a comparison lambda using expression tree. Will we use Binary.. or Boolean….?
Q: foreach on my custom class … will call which methods — MoveNext/Current or GetEnumerator()
Q: calling ToUpper() on a dynamic variable, where ToUpper is both an instance method and an extension method?
%%A: instance meth takes precedence. Ext method may not be found at all. But there are workarounds.

Q: benefit of compiling an expression tree?
Q: can I assign twice to an out parameter within Method1? I think there’s no restriction.
Q: how to p/invoke on a win32 DLL
Q: execution order between base ctor, my ctor, static ctor of a type used in my ctor
Q: GetType().ToString() on System.NotSupportedException shows “System….” ?
Q: linq group-by

Q: can Main() method take 0 parameter?
AA: yes

Q: in Main(), can I initialize a variable before passing it to a out parameter of Method1?
%%A: yes optional. Pre-initialize is compulsory for ref-params and optional for out-params. Consequently, the method is requried to
populate out-param (since pre-initlialize was possibly skipped) but not required for ref-params.

Q: which is a managed resource – file handle, memory stream, socket, windows handle, db conn?
A: socket

Q: throw; vs throw ex;
A: throw; is better — more complete stack trace. see stack overflow

Q: can you pass an anonymous delegate into Thread ctor?
A: quite common

Q: static readonly field – set in static ctor or declaration?
A: both

c# cod`IV – struct/disconnected

–req#0–
O(1): Insert(Employee e)
O(1): Delete(int id)
O(1): LookupById(int id)
O(1): LookupByEmail(string email)
–req#1–
Must not corrupt:
EmployeeLookup el = new EmployeeLookup();
Employee e = new Employee(1, “one@example.com“);
el.Insert(e);
e.Id = 5;
MUST BE TRUE: el.LookupById(1).Id == 1
MUST BE FALSE: e.Id = el.LookupbyId(1).Id
e = el.LookupById(1);
e.Id = 10;
MUST BE TRUE: el.LookupById(1).Id == 1
MUST BE FALSE: e.Id = el.LookupbyId(1).Id
—– my solution:
public struct Employee{
public int id;
public string em;
}
public class EL where T: struct {//EmployeeLookup
Dictionary d1 = new…;
Dictionary d2 = new…;
 //d1 add and d2 add should both fail or both succeed
bool Insert(T emp){//insert into d1/d2
if (!d1.TryAdd(emp.id, emp)) return false;
if (!d2.TryAdd(emp.email, emp)) {
d1.Remove(emp.id); //rollback
return false;
}
return true;
}
Employee //struct
LookupById(int id){
Employee found;
if (!d1.TryGetValue(id, out found)){//log and throw….
}
return found; //struct
}
}

c# IV – Eikon pre-screening

This is a 1) Knowledge based and 2) algo-based IV. The areas covered are evergreen and stable.

TCP vs UDP
ArrayList vs List
Mutex vs Semaphore — see other blog

Q: lock vs Mutex
%%A: any reference type object can be a lock…

Q3a: implement a data structure with random access and fast add/remove on both ends.
%%A: deque, using sements linked by a directory, as in STL
A: now I know circular array is simpler.

Q3b: How about the directory data structure in your deque
%%A: perhaps a hashtable?
A: Now I know it’s a vector of pointers

Q: 2 servers to synch their clocks on startup. No need for correct time, just the same time.
%%A: Side B will query A (or receive broadcasts) and update itslef. Side A will blindly broadcast. Both query and broadcast are
simple TCP operations.

c# – some must-know but seldom used features#le2YH

(Blog post. No need to reply.)

Hi YH,

Sharing some recent experience. In any language, the features we need to use is a tiny portion of the language feature set. Many of these features are designed for robust, high-performance, exception-safe coding but most applications have no such requirement.

However, As an experienced c# coder, we need to know enough to carry a intelligent discussion with other veterans on these topics. Otherwise we look like fake:)

* unsafe code
* p/invoke
* reflection on Generic type
* custom attributes (like java annotation)
* expression tree
* dynamic keyword
* closures
* linq to objects
* linq group-by
* GC intricacies
* Dispose vs Finalizer. When to use
* empty throw; vs throw ex;
* new MyStruct()
* SafeHandle
* interlocked
* override ToString() for a custom MyStruct
* wait/pulse
* synchronization context

All of the above features I didn’t need in my c# programming. However, I did go out of my way to explore c#, and managed to use these useful constructs
* generic type constraints
* submit a task to thread pool
* wait handles