a few CORE differences – c# over java

(Let’s be brief, incomplete…Page numbers refer to [[C# precisely]] )
— fundamental differences among the myriad differences
Diff — delegates, events, lambda – expanded C++ stateless functor
Diff — non-virtual method? counter-intuitive to both C++ and java guys,
Diff: yield
diff: enums. Fundamentally different.  A Java enum type is a “singleton” class.
Diff — generics
Diff — expression tree

–fundamental but less exploited
Diff — ref param, out param
** assignment to a method param are visible to caller method ! P71
Diff — hiding rule — less clean than java. Even more complicated than C++ hiding rules
** you can even hide a virtual method! P 75

Diff: struct? a “kernel” innovation but unimportant in “userland”. P54
Diff: simple (i.e. primitive) types are aliases of struct types. Replaces autoboxing. Fundamentally they are same as java primitives
Diff: operator overloading like ==. Similar to equals() override in J
diff: access modifiers “internal”, default. Similar to “package access” in J
diff: Integration of primitive and wrapper classes into structs — primitive wrappers glorified
diff: simple types having methods.
–higher-level or local/peripheral features
diff: explicit interface members
class properties and indexers? accessors glorified
implicit user-defined type conversions? tricky and not widely used
IDisposable/using — “finally” glorified
rectangular/jagged arrays? Only one of them is widely used.
all nested classes are all static
static classes
static ctor

c++ Function hiding – free func OR member func

c++ has (non-trivial) hiding rules for member functions AND free functions …. See P37 / P236 [[effC++]].

I feel c++ method hiding is best studied along with overriding/overloading. See http://bigblog.tanbin.com/2011/12/hiding-redefining-overriding.html

For other forms of hiding, see my blog posts http://bigblog.tanbin.com/search/label/c%2B%2Bc%23java_hiding

Within an inheritance hierarchy, Java supports static method hiding; C# uses “new” to make hiding explicit.

overload^override – c++ (java too)

I consider overloading and overriding 2 magic tricks by the compiler. Here are a few contrasts as far as I can see.
Example of overloading —
function1(B* arg);
function1(D* arg);

– Overloading is compile-time magic; overriding is run-time magic. If you have a D object’s address in a variable myVar and you pass it function1, which function1 is chosen by compiler? Depends on the declared type of myVar. Discussed repeatedly in my blog.

– consider renaming to function1_for_Base()/function1_for_Derived() etc. It may seem cool to have a bunch of overload functions, but in one Barcap email sender utility class, there are 4 send(…) utilities each with more than 7 parameters — code smell. It’s hard for users to tell them apart. P403 [[c++TimesavingTechniques]] points out that overloading complicates debugging and maintenance.
** Readability is fine in overRiding

– Overriding is generally a best practice to be adopted whenever possible. I can’t say the same about overloading.
– c++ has hiding rule about overLoading. No such thing about overRiding.
– c++ does implicit (!) type conversion about overLoading.
– In conclusion, overriding is cleaner than overloading, less complicated, and more readable.
– In overriding There’s more magic by compiler — vptr etc. More powerful but Not more complicated
– overLoad can be applied to operators such as op=, op+. I doubt overRide can

c++ method hiding, redefining, overriding – fundamentals

Background — When reading a particular function call in the context of a c++ class hierarchy, we need to identify exactly which function is selected at compile/runtime. In the case of “No match”, we get a compile-time error (never run time?).

Non-trivial. It’s easy to lose focus. Focus on the fundamental principles — only a few.

– Fundamental — override is strict [1]. If overriding, then vtbl dynamic binding. Simple and clear. Otherwise, it’s always, always static binding.
– Fundamental — if static binding, then remember the hiding rule. Per-name basis — See [[Eff C++] last item. As a result, some base class methods become unavailable — compiler errors. [3]
– Fundamental — compiler attempts implicit type conversion on every argument.

Redefining is an important special case of hiding, but fundamentally, it’s plain vanilla function hiding.

It was said that Overriding resolution is done “after” hiding? Does it mean that the hiding rules kick in first before system goes through overriding resolution? But I don’t think hiding would kick in at all.

[1] see http://bigblog.tanbin.com/2011/02/runtime-binding-is-highly-restrictive.html
[3] Fixable with a local “using” directive — Using Defeats Hiding

field hiding by subclass, learning notes

(c# has the trickiest hiding rules; c++ has  more than java.)

First, remember the onion model described in other posts. To rephrase one more time, each instance field occupies memory “cells” in a layer of the onion. If class B has an instance field vf, and subclass C has a same-name instance field vf, then a C “onion” has storage for both fields.

myRef.vf resolves to one of the 2 fields at compile time depending on declared type of myRef. P40 [[java precisely]]

On P25 [[java precisely]], B has a static field sf, and so does C. The C onion in memory has NO storage for either field, but it has a pointer to the class object, which has storage for the field.

Q: does the C class object have storage for both static fields?
%%A: probably no. C class object just needs a pointer to B class object.

Question: “myRef.sf” refers to …? P40 [[java precisely]]
A: At compile time, if the C onion is declared as type B, then the field is B.sf
A: At compile time, if the C onion is declared as type C, then the field is C.sf

I feel the static and non-static cases are similar — both compile-time binding. This is the simple rule for field binding. For method call binding, static and non-static behave differently. Remember that runtime binding is very strict and requires non-static and non-field, among other conditions. Failing any condition means compile-time binding.

c# q(NEW) keyword – 3 meanings

I’m sure there are excellent online articles, but here’s my own learning note.

Java “new” always hits Heap, period. Simple and clean.

C++ has array-new, placement-new, and class-specific-new. C++ “new” almost always hits the heap except
– except placement-new
– except you can customize op-new for your class to hit your allocator.

C# “new” doesn’t always mean Heap. The code “new MyStruct” usually hits the stack rather than the heap. See P55[[c#precisely]] for a nice diagram.

C# actually gives 3 unrelated (mildly confusion) meanings to the “new” keyword. One is the Java meaning. The 2nd meaning is “hide base type Member” and can apply to
* virtual methods — Most confusing
* non-virtual methods
* fields
* nested classes/interfaces
* events??

“Type” can be a base interface.

3rd meaning – select-new creates an instance of an anonymous type [3]. See http://www.dotnetperls.com/select-new.  http://stackoverflow.com/questions/2263242/select-new-keyword-combination is a summary of select-new

[3] java also let’s you create an instance of an anonymous type but you need to specify the supertype.

overriding vs field hiding in java and c++

[[Java precisely]] P40 summarizes

· In a non-static field access o.f, the field referred to is determined by the compile-time type of the object expression o
· In a non-static call to a non-private method o.m(), the method called is determined by the run-time class of the target object: the object to which o evaluates to

Say C.java extends B.java,

Q: if you only have an object o=new C(), how can you access f and m() declared in B.java?
A: With the exception below, you can’t access B::m(). The method call o.m() resolves at run time and always binds to C::m(). However, f is a different story. You can cast o to B and o.f would refer to B::f

A special context — super.f and super.m() do give you access to parent’s members, but you can only use this syntax in C’s constructors or non-static methods, essentially in C.java source code.

I wonder what C++ does.. Here are some tidbits.

o.B::m() actually let’s you call parent’s m() via a subclass object. Also see Item 50 in [[eff c++]]

inherit static methods?

–I guess not inherited:
a static method m1 is tied to the super class. I think A subclass can only define another m1 to hide it.

Refer to the other post on “superclass instance inside subclass instance”. Static members are not INSIDE the onion and not inherited.

— Now I believe yes inherited:
P 22 [[ java precisely ]] says “inherits all methods … but not the constructors”
p 45 has a real example to prove that the superclass static method is still accessible even if shadowed (hidden) by a subclass static method (of the same signature, of course)

onion&&remote-control — static binding

Runtime binding is covered in a few posts with onion and remote-control. Now let’s apply our analogies to static method binding. P 45 [[ java precisely ]] has a good example 59.

C2 c2 = new C2(); // C2 extends C1 and hides a static method C1.m1() with C2.m1()
C1 c1 = c2;

Now c1 and c2 are 2 remote controls programmed for a single onion, the “biggest onion” [1]. However,
* variable c1 is a remote control of type C1 and supports C1.java’s static m1() only
* variable c2 supports C2.java’s static m1() only.

Now the question:
Q: how are the various calls to m1() resolved.
A: C1.m1() and C2.m1() are obvious.
A: c1.m1() binds to C1.java static m1(). The onion, which happens to be a C2 onion, doesn’t affect the resolution.
A: c2.m1() binds to C2.m1()

[1] Therefore instance methods c1.m1(int) and c2.m1(int) {c1 c2 both lower-case} are both bound to C2.java m1(int). Runtime binding of instance method m1(int).