Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# vs VB.Net, what's the difference between Shadowing and [Overloading (without changing the arguments)]

Sorry for the long question but I'm kinda new to C# (I used to use VB.Net)

I fully understand the difference between Overriding and Overloading in both VB.Net and C#.. so there's no problem with the overriding.

Now, in VB.Net there's a difference between Shadowing (using the keyword Shadows) and Overloading (using the keyword Overloads 'with the same arguments') as follows:

  • When using Shadows, it shadows every method with the same name -regardless of the arguments- to become one method only (the shadowed method).
  • When using Overloads -with the same arguments-, it overloads (shadows) only the method with the same name and arguments.

Consider this code:

Class A
    Sub MyMethod()
        Console.WriteLine("A.MyMethod")
    End Sub
    Sub MyMethod(ByVal x As Integer)
        Console.WriteLine("A.MyMethod (x)")
    End Sub
    Sub MyMethod2()
        Console.WriteLine("A.MyMethod2")
    End Sub
    Sub MyMethod2(ByVal x As Integer)
        Console.WriteLine("A.MyMethod2 (x)")
    End Sub
End Class

Class B
    Inherits A
    Overloads Sub MyMethod()
        Console.WriteLine("B.MyMethod")
    End Sub
    Shadows Sub MyMethod2()
        Console.WriteLine("B.MyMethod2")
    End Sub
End Class

Then:

Dim obj As New B()
obj.MyMethod()      'B.MyMethod
obj.MyMethod(10)    'A.MyMethod (x)
obj.MyMethod2()     'B.MyMethod2

While:

obj.MyMethod2(10)   'Error, cuz there's only one 'MyMethod2' (and with zero arguments)

So far so good..

BUT, in C# I'm not getting the same difference between Shadowing (using the keyword New) and Overloading (Same name & arguments)!

So, when trying the same code above in C# (using C# syntax of course :D), the following line:

obj.MyMethod2(10);

will return>> 'A.MyMethod2 (x)'

Looks like no difference between Overloading and Shadowing in C#!!

Anyone can explain why this discrepancy exists?

Thank you

like image 721
41686d6564 stands w. Palestine Avatar asked Jan 13 '16 14:01

41686d6564 stands w. Palestine


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C full form?

Originally Answered: What is the full form of C ? C - Compiler . C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie to develop the UNIX operating system at Bell Labs. C was originally first implemented on the DEC PDP-11 computer in 1972.

How old is the letter C?

The letter c was applied by French orthographists in the 12th century to represent the sound ts in English, and this sound developed into the simpler sibilant s.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

This is a bit of a confusing question. Let me break it down into smaller questions.

What is inheritance?

When one type inherits from another, the inheritable members of the base type are also members of the derived type. Most members are inheritable; a few, like constructors, are not.

All members? Even private ones?

Yes. Private members are inherited. It may not be legal to look them up by name, but they are still inherited.

In C#, what is overloading a method?

A method is overloaded when there are two methods of the same name but different signatures in one type. (For the purposes of this discussion, the signature of a method consists of its name, generic arity, number of parameters, and parameter types.)

If we have a type D that has two members, M(X) and M(Y), that are overloaded, it is perfectly fine for one of them to be inherited from a base type B, and the other declared in D. They are still overloads.

In C#, how are overloads resolved?

The process is complex, but the basic rules are: first a collection of all accessible methods of the given name is assembled. Then all methods where the signatures do not match the given arguments are removed. The remaining methods are the applicable methods.

Then the methods that are declared in the most derived type are identified and kept; the rest of the applicable methods are removed. (Overridden methods are considered to be methods of the type which originally declared the method, not the type which overrode them.)

If one method remains, it wins. Otherwise, every pair of applicable methods is evaluated to see whether one is better than the other at matching the arguments; any method that is worse than another is eliminated. If this process produces a unique best method then it wins.

There are many more rules involving generic methods and tiebreakers that are not relevant to this discussion.

In C#, what is hiding by name for methods?

If you have a method M(X) in the base class that is inherited by the derived class, the derived class may declare another member of the same signature. This member hides the member in the base class.

In particular, if the hiding method is an applicable method then overload resolution will choose the hiding method over any base type member because, as we already know, overload resolution discards members that were not in the most derived type. Since a hiding method is always in a more derived type than the hidden method, it always wins -- provided it is accessible of course.

In C# how do we mark a member as hiding by name?

You are not required to do anything; simply declaring the member hides the base class member. However, the C# compiler will warn you that the hiding might be unintentional; it often is. You can make the warning go away by using the new keyword on the hiding member. This is the best practice when you intend to hide a member.

In C#, what happens if overload resolution cannot pick a hiding method because it is inapplicable or inaccessible?

Then the usual rules of overload resolution apply. The hiding method is not applicable, so it is removed from the set of methods under consideration immediately. This could mean that no methods declared in the derived type are applicable, and therefore members of the base class might be the applicable methods declared in the most derived type.

Is the rule for how member shadowing works in VB slightly different than the hiding rules in C#?

Yes.

Why?

C# and VB, though deliberately similar, are not different costumes on the same actor. They're different languages with different histories, different design considerations, and different design teams. You should expect small differences like this.

So what is the difference between hiding a method and overloading a method in C#?

Both declare a new member. Adding a new overload adds a method with a different signature, and the methods might or might not be declared in the same type. Hiding a method adds a new method that exactly matches the signature of a method in a base type.

like image 190
Eric Lippert Avatar answered Oct 31 '22 11:10

Eric Lippert


C# and VB may use the same framework and IL, but they are not the same language or platform. Some features in C# do not exist in VB, and some features in VB do not exist in C#.

In this case, using the New keyword on a method in C# does not do "shadowing". It is used for method hiding.

like image 20
Joel Coehoorn Avatar answered Oct 31 '22 10:10

Joel Coehoorn