Compile time polymorphism vs. run time polymorphism - c#

Why is overloading called compile time polymorphism and Overriding run time polymorphism in C#?

Well, overloading decisions (which method signatures are used, based on the arguments1) are made by the compiler, whereas overriding decisions (which method implementations are used, based on the type of the target of the method) are made by the CLR at execution time.
I wouldn't usually call overloading "polymorphism" though. In my experience the word usually refers to overriding. I suppose overloading does allow you to treat an object of one type as another, although overloading itself doesn't need to be involved there - it's just normal type conversions.
Here's an example showing that overload choice is performed at compile time:
using System;
class Test
{
static void Foo(object a)
{
Console.WriteLine("Object overload called");
}
static void Foo(string a)
{
Console.WriteLine("String overload called");
}
static void Main()
{
object x = "hello";
Foo(x);
}
}
Here the Foo(object) overload is called because x is of type object at compile time - it's only at execution time that it's known to refer to a string.
Compare that with this example:
using System;
class Base
{
public virtual void Foo()
{
Console.WriteLine("Base.Foo called");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived.Foo called");
}
}
class Test
{
static void Main()
{
Base x = new Derived();
x.Foo();
}
}
Here the compile-time type of x is Base, but it's still the derived class's overriding method which is called, because the execution-time type of the object that x refers to is Derived.
1 It's slightly more complicated than that in fact, due to method hiding etc - but in simple cases you can think of it as just picking the signature.

Overridden functions are functions that have the same signature, but are implemented in different derived classes. At compile time, usually the base class type is used to reference an object, though at run time this object could be of a derived type, so when an overridden method is called, the implementation that is called is dependent on what kind of object is doing the calling (base vs. a derived type) which is unknown at compile time.
Overloading (not really polymorphism) is simply multiple functions which have the same name but different signatures (think multiple constructors for an object taking different numbers of arguments). Which method is called is known at compile time, because the arguments are specified at this time.

Polymorphism
Through inheritance, a class can be used as more than one type; it can be used as its own type, any base types, or any interface type if it implements interfaces. This is called polymorphism.
Polymorphism means having more than one form. Overloading and overriding are used to implement polymorphism. Polymorphism is classified into compile time polymorphism or early binding or static binding and Runtime polymorphism or late binding or dynamic binding.
Overriding - same method names with same arguments and same return types associated in a class and its subclass. Overriding in C# makes use of the "override" keyword. To override a method means to replace it with a new way of handling data.
Overloading - same method name with different arguments, may or may not be same return type written in the same class itself.
Compile time Polymorphism or Early Binding
The polymorphism in which compiler identifies which polymorphic form it has to execute at compile time it self is called as compile time polymorphism or early binding.
Advantage of early binding is execution will be fast. Because every thing about the method is known to compiler during compilation it self and disadvantage is lack of flexibility.
Examples of early binding are overloaded methods, overloaded operators and overridden methods that are called directly by using derived objects.
Runtime Polymorphism or Late Binding
The polymorphism in which compiler identifies which polymorphic form to execute at runtime but not at compile time is called as runtime polymorphism or late binding.
Advantage of late binding is flexibility and disadvantage is execution will be slow as compiler has to get the information about the method to execute at runtime.
Example of late binding is overridden methods that are called using base class object.
class A
{
public virtual void Leg(string Name)
{
}
}
class B:A
{
public override void Leg(string Name)
{
}
}
Example for Over loading
class A
{
void a()
{
}
void a(string Name)
{
}
}
In other words, "Many forms of a single object is called Polymorphism."
Eg:
A Team Leader behaves to Sub Ordinate.
A Team Leader behaves to his/her seniors.
A Team Leader behaves to other Team Leaders.
Here Team Leader is an object but attitude is different in different situation.
Difference between Method Overriding and Method hiding
Method overriding allows a subclass to provide a specific implementation of a method that is already provided by base class. The implementation in the subclass overrides (replaces) the implementation in the base class.
The important thing to remember about overriding is that the method that is doing the overriding is related to the method in the base class.
When a virtual method is called on a reference, the actual type of the object to which the reference refers is used to determine which method implementation should be used. When a method of a base class is overridden in a derived class (subclass), the version defined in the derived class is used. This is so even should the calling application be unaware that the object is an instance of the derived class.
Method hiding does not have a relationship between the methods in the base class and derived class. The method in the derived class hides the method in the base class.

compile time polymorphism
Suppose lets say you have 2 methods as follows; since the method shares same name but have different parameters; it is called as "overloaded" method.
Eat(string food);
Eat(string food, string SpoonOrFork);
and you are using like this in your dinner class
public class Man
{
public bool Eat (string food)
{
//implementation
}
public bool Eat (string food, string SpoonOrFork)
{
//implementation
}
}
public class dinner
{
public bool Start()
{
string food = "course1";
Man.Eat ( food);
}
}
Now when you compile this program the compiler knows exactly which version of Eat method to call during compile time itself (because of the difference in parameters).
That's why it is called as compile time polymorphism.
Run time polymorphism
public class chimp
{
public virtual void walk()
{
Console.WriteLine("I am walking using 4 legs");
}
}
public class neanderthals : chimp
{
public override void walk()
{
Console.WriteLine("I am walking using 2 legs");
}
}
class Program
{
static void Main(string[] args)
{
chimp x = new neanderthals();
x.walk();
Console.ReadLine(); // this will give an output of "I am walking using 2 legs"
}
}
In the above code x is of type chimp. Even though the compiler thinks it is going to call the walk method in chimp; but that is not what actually happens. Since it depends on CLR (run time) this kind of polymorphism is called "run-time" polymorphism.

Polymorphism
Polymorphism means many forms (ability to take more than one form). In Polymorphism poly means “multiple” and morph means “forms” so polymorphism means many forms.
In polymorphism we will declare methods with same name and different parameters in same class or methods with same name and same parameters in different classes. Polymorphism has ability to provide different implementation of methods that are implemented with same name.
In Polymorphism we have 2 different types those are
- Compile Time Polymorphism (Called as Early Binding or Overloading or static binding)
- Run Time Polymorphism (Called as Late Binding or Overriding or dynamic binding)
Compile Time Polymorphism
Compile time polymorphism means we will declare methods with same name but different signatures because of this we will perform different tasks with same method name. This compile time polymorphism also called as early binding or method overloading.
Method Overloading or compile time polymorphism means same method names with different signatures (different parameters)
For more details check this link polymorphism in c#
Run Time Polymorphism
Run time polymorphism also called as late binding or method overriding or dynamic polymorphism. Run time polymorphism or method overriding means same method names with same signatures.
In this run time polymorphism or method overriding we can override a method in base class by creating similar function in derived class this can be achieved by using inheritance principle and using “virtual & override” keywords.

Compile time Polymorphism
Compile time Polymorphism is also known as method overloading.
Method overloading means having two or more methods with the same name but with different signatures.
Run time Polymorphism
Run time Polymorphism is also known as method overriding.
Method overriding means having two or more methods with the same name and same signature, but with a different implementation

Run time Polymorphism Example in c#.
using System;
public class demo{
public static void Main(String[] args){
cal cal ;
add a = new add();
cal = a;
Console.WriteLine("Addition is" + cal.calculate(20, 20));
sub s = new sub();
cal = s;
Console.WriteLine("Substraction is" + cal.calculate(20, 20));
mul m = new mul();
cal = m;
Console.WriteLine("Multiplication is" + cal.calculate(20, 20));
div d = new div();
cal = d;
Console.WriteLine("Division is" + cal.calculate(20, 20));
Console.ReadLine();
}
}
public abstract class cal{
public abstract int calculate(int a, int b);
}
public class add : cal {
public override int calculate(int a ,int b){
return a+b;
}
}
public class sub : cal{
public override int calculate(int a, int b){
return a-b;
}
}
public class mul : cal{
public override int calculate(int a, int b){
return a*b;
}
}
public class div : cal{
public override int calculate(int a, int b){
return a/b;
}
}

Because it's known at compile time which of your overloaded functions is called, but that is not always the case for an overridden function.

Classical examples of static polimorphism are based on template metaprogramming or Duck Typing but not on method overloading.
Static polimorphism means that desicion is made by compilier (statically), and dynamic polimorphism means that desition is made only in runtime (dynamically).

Related

Polymorphism with generics - strange behavior

Pluggable framework
Imagine a simple pluggable system, which is pretty straightforward using inheritance polymorphism:
We have a graphics rendering system
There are different types of graphics shapes (monochrome, color, etc.) that need rendering
Rendering is done by a data-specific plugin, e.g. a ColorRenderer will render a ColorShape.
Every plugin implements IRenderer, so they can all be stored in an IRenderer[].
On startup, IRenderer[] is populated with a series of specific renderers
When data for a new shape is received, a plugin is chosen from the array based on the type of the shape.
The plugin is then invoked by calling its Render method, passing the shape as its base type.
The Render method is overridden in each descendant class; it casts the Shape back to its descendant type and then renders it.
Hopefully the above is clear-- I think it is a pretty common sort of setup. Very easy with inheritance polymorphism and run-time casting.
Doing it without casting
Now the tricky part. In response to this question, I wanted to come up with a way to do this all without any casting whatsoever. This is tricky because of that IRenderer[] array-- to get a plugin out of the array, you would normally need to cast it to a specific type in order to use its type-specific methods, and we can't do that. Now, we could get around that by interacting with a plugin only with its base class members, but part of the requirements was that the renderer must run a type-specific method that has a type-specific data packet as an argument, and the base class would not be able to do that because there is no way to pass it a type-specific data packet without a casting it to the base and then back to the ancestor. Tricky.
At first I thought it was impossible, but after a few tries I found I could make it happen by juking the c# generic system. I create an interface that is contravariant with respect to both plugin and shape type and then used that. Resolution of the renderer is decided by the type-specific Shape. Xyzzy, the contravariant interface makes the cast unnecessary.
Here is the shortest version of the code I could come up with as an example. This compiles and runs and behaves correctly:
public enum ColorDepthEnum { Color = 1, Monochrome = 2 }
public interface IRenderBinding<in TRenderer, in TData> where TRenderer : Renderer
where TData: Shape
{
void Render(TData data);
}
abstract public class Shape
{
abstract public ColorDepthEnum ColorDepth { get; }
abstract public void Apply(DisplayController controller);
}
public class ColorShape : Shape
{
public string TypeSpecificString = "[ColorShape]"; //Non-virtual, just to prove a point
override public ColorDepthEnum ColorDepth { get { return ColorDepthEnum.Color; } }
public override void Apply(DisplayController controller)
{
IRenderBinding<ColorRenderer, ColorShape> renderer = controller.ResolveRenderer<ColorRenderer, ColorShape>(this.ColorDepth);
renderer.Render(this);
}
}
public class MonochromeShape : Shape
{
public string TypeSpecificString = "[MonochromeShape]"; //Non-virtual, just to prove a point
override public ColorDepthEnum ColorDepth { get { return ColorDepthEnum.Monochrome; } }
public override void Apply(DisplayController controller)
{
IRenderBinding<MonochromeRenderer, MonochromeShape> component = controller.ResolveRenderer<MonochromeRenderer, MonochromeShape>(this.ColorDepth);
component.Render(this);
}
}
abstract public class Renderer : IRenderBinding<Renderer, Shape>
{
public void Render(Shape data)
{
Console.WriteLine("Renderer::Render(Shape) called.");
}
}
public class ColorRenderer : Renderer, IRenderBinding<ColorRenderer, ColorShape>
{
public void Render(ColorShape data)
{
Console.WriteLine("ColorRenderer is now rendering a " + data.TypeSpecificString);
}
}
public class MonochromeRenderer : Renderer, IRenderBinding<MonochromeRenderer, MonochromeShape>
{
public void Render(MonochromeShape data)
{
Console.WriteLine("MonochromeRenderer is now rendering a " + data.TypeSpecificString);
}
}
public class DisplayController
{
private Renderer[] _renderers = new Renderer[10];
public DisplayController()
{
_renderers[(int)ColorDepthEnum.Color] = new ColorRenderer();
_renderers[(int)ColorDepthEnum.Monochrome] = new MonochromeRenderer();
//Add more renderer plugins here as needed
}
public IRenderBinding<T1,T2> ResolveRenderer<T1,T2>(ColorDepthEnum colorDepth) where T1 : Renderer where T2: Shape
{
IRenderBinding<T1, T2> result = _renderers[(int)colorDepth];
return result;
}
public void OnDataReceived<T>(T data) where T : Shape
{
data.Apply(this);
}
}
static public class Tests
{
static public void Test1()
{
var _displayController = new DisplayController();
var data1 = new ColorShape();
_displayController.OnDataReceived<ColorShape>(data1);
var data2 = new MonochromeShape();
_displayController.OnDataReceived<MonochromeShape>(data2);
}
}
If you run Tests.Test1() the output will be:
ColorRenderer is now rendering a [ColorShape]
MonochromeRenderer is now rendering a [MonochromeShape]
Beautiful, it works, right? Then I got to wondering... what if ResolveRenderer returned the wrong type?
Type safe?
According to this MSDN article,
Contravariance, on the other hand, seems counterintuitive....This seems backward, but it is type-safe code that compiles and runs. The code is type-safe because T specifies a parameter type.
I am thinking, there is no way this is actually type safe.
Introducing a bug that returns the wrong type
So I introduced a bug into the controller so that is mistakenly stores a ColorRenderer where the MonochromeRenderer belongs, like this:
public DisplayController()
{
_renderers[(int)ColorDepthEnum.Color] = new ColorRenderer();
_renderers[(int)ColorDepthEnum.Monochrome] = new ColorRenderer(); //Oops!!!
}
I thought for sure I'd get some sort of type mismatch exception. But no, the program completes, with this mysterious output:
ColorRenderer is now rendering a [ColorShape]
Renderer::Render(Shape) called.
What the...?
My questions:
First,
Why did MonochromeShape::Apply call Renderer::Render(Shape)? It is attempting to call Render(MonochromeShape), which obviously has a different method signature.
The code within the MonochromeShape::Apply method only has a reference to an interface, specifically IRelated<MonochromeRenderer,MonochromeShape>, which only exposes Render(MonochromeShape).
Although Render(Shape) looks similar, it is a different method with a different entry point, and isn't even in the interface being used.
Second,
Since none of the Render methods are virtual (each descendant type introduces a new, non-virtual, non-overridden method with a different, type-specific argument), I would have thought that the entry point was bound at compile time. Are method prototypes within a method group actually chosen at run-time? How could this possibly work without a VMT entry for dispatch? Does it use some sort of reflection?
Third,
Is c# contravariance definitely not type safe? Instead of an invalid cast exception (which at least tells me there is a problem), I get an unexpected behavior. Is there any way to detect problems like this at compile time, or at least to get them to throw an exception instead of doing something unexpected?
OK, first of all, do not write generic types like this. As you have discovered, it rapidly becomes a huge mess. Never do this:
class Animal {}
class Turtle : Animal {}
class BunchOfAnimals : IEnumerable<Animal> {}
class BunchOfTurtles : BunchOfAnimals, IEnumerable<Turtle> {}
OH THE PAIN. Now we have two paths by which to get an IEnumerable<Animal> from a BunchOfTurtles: Either ask the base class for its implementation, or ask the derived class for its implementation of the IEnumerable<Turtle> and then covariantly convert it to IEnumerable<Animal>. The consequences are: you can ask a bunch of turtles for a sequence of animals, and giraffes can come out. That's not a contradiction; all the capabilities of the base class are present in the derived class, and that includes generating a sequence of giraffes when asked.
Let me re-emphasize this point so that it is very clear. This pattern can create in some cases implementation-defined situations where it becomes impossible to determine statically what method will actually be called. In some odd corner cases, you can actually have the order in which the methods appear in the source code be the deciding factor at runtime. Just don't go there.
For more on this fascinating topic I encourage you to read all the comments to my 2007 blog post on the subject: https://blogs.msdn.microsoft.com/ericlippert/2007/11/09/covariance-and-contravariance-in-c-part-ten-dealing-with-ambiguity/
Now, in your specific case everything is nicely well defined, it's just not defined as you think it ought to be.
To start with: why is this typesafe?
IRenderBinding<MonochromeRenderer, MonochromeShape> component = new ColorRenderer();
Because you said it should be. Work it out from the point of view of the compiler.
A ColorRenderer is a Renderer
A Renderer is a IRenderBinding<Renderer, Shape>
IRenderBinding is contravariant in both its parameters, so it may always be made to have a more specific type argument.
Therefore a Renderer is an IRenderBinding<MonochromeRenderer, MonochromeShape>
Therefore the conversion is valid.
Done.
So why is Renderer::Render(Shape) called here?
component.Render(this);
You ask:
Since none of the Render methods are virtual (each descendant type introduces a new, non-virtual, non-overridden method with a different, type-specific argument), I would have thought that the entry point was bound at compile time. Are method prototypes within a method group actually chosen at run-time? How could this possibly work without a VMT entry for dispatch? Does it use some sort of reflection?
Let's go through it.
component is of compile-time type IRenderBinding<MonochromeRenderer, MonochromeShape>.
this is of compile-time type MonochromeShape.
So we are calling whatever method implements IRenderBinding<MonochromeRenderer, MonochromeShape>.Render(MonochromeShape) on a ColorRenderer.
The runtime must figure out which interface is actually meant. ColorRenderer implements IRenderBinding<ColorRenderer, ColorShape> directly and IRenderBinding<Renderer, Shape> via its base class. The former is not compatible with IRenderBinding<MonochromeRenderer, MonochromeShape>, but the latter is.
So the runtime deduces that you meant the latter, and executes the call as though it were IRenderBinding<Renderer, Shape>.Render(Shape).
So which method does that call? Your class implements IRenderBinding<Renderer, Shape>.Render(Shape) on the base class so that's the one that's called.
Remember, interfaces define "slots", one per method. When the object is created, each interface slot is filled with a method. The slot for IRenderBinding<Renderer, Shape>.Render(Shape) is filled with the base class version, and the slot for IRenderBinding<ColorRenderer, ColorShape>.Render(ColorShape) is filled with the derived class version. You chose the slot from the former, so you get the contents of that slot.
Is c# contravariance definitely not type safe?
I promise you it is type safe. As you should have noticed: every conversion you made without a cast was legal, and every method you called was called with something of a type that it expected. You never invoked a method of ColorShape with a this referring to a MonochromeShape, for instance.
Instead of an invalid cast exception (which at least tells me there is a problem), I get an unexpected behavior.
No, you get entirely expected behaviour. You just have created a type lattice that is extraordinarily confusing, and you don't have a sufficient level of understanding of the type system to understand the code you wrote. Don't do that.
Is there any way to detect problems like this at compile time, or at least to get them to throw an exception instead of doing something unexpected?
Don't write code like that in the first place. Never implement two versions of the same interface such that they may unify via covariant or contravariant conversions. It is nothing but pain and confusion. And similarly, never implement an interface with methods that unify under generic substitution. (For example, interface IFoo<T> { void M(int); void M(T); } class Foo : IFoo<int> { uh oh } )
I considered adding a warning to that effect, but it was difficult to see how to turn off the warning in the rare cases where it is desirable. Warnings that can only be turned off with pragmas are poor warnings.
First. MonochromeShape::Apply call Renderer::Render(Shape) because of the following:
IRenderBinding<ColorRenderer, ColorShape> x1 = new ColorRenderer();
IRenderBinding<Renderer, Shape> x2 = new ColorRenderer();
// fails - cannot convert IRenderBinding<ColorRenderer, ColorShape> to IRenderBinding<MonochromeRenderer, MonochromeShape>
IRenderBinding<MonochromeRenderer, MonochromeShape> c1 = x1;
// works, because you can convert IRenderBinding<Renderer, Shape> toIRenderBinding<MonochromeRenderer, MonochromeShape>
IRenderBinding<MonochromeRenderer, MonochromeShape> c2 = x2;
So in short: ColorRenderer inherits from Renderer and that in turn implements IRenderBinding<Renderer, Shape>. This interface is what allows ColorRendered to be implicitly converted to IRenderBinding<MonochromeRenderer, MonochromeShape>. This interface is implemented by class Renderer and so it's not suprising that Renderer.Render is called when you call MonochromeShape::Apply. The fact you pass instance of MonochromeShape and not Shape is not a problem exactly because TData is contravariant.
About your second question. Dispatch by interface is virtual just by definition. In fact, if method implements some method from interface - it's marked as virtual in IL. Consider this:
class Test : ITest {
public void DoStuff() {
}
}
public class Test2 {
public void DoStuff() {
}
}
interface ITest {
void DoStuff();
}
Method Test.DoStuff has following signature in IL (note virtual:
.method public final hidebysig virtual newslot instance void
DoStuff() cil managed
Method Test2.DoStuff is just:
.method public hidebysig instance void
DoStuff() cil managed
As for third question I think it's clear from above that it behaves as expected and is type-safe exactly because no invalid cast exceptions are possible.

C#: Why does safe casting (as) return overridden methods instead of base methods?

Looking at how the as keyword works in C#, I can see that it allows for casting where explicit casting (i.e. using brackets) prevents compilation.
However In the code below I find that if I override a method in a derived class, and then safe cast as the base class, that the overridden method in the derived class still executes. Why is this? I was expecting the method as defined on the base class to execute instead.
class Base
{
public override string ToString()
{
return base.ToString();
}
public string OtherMethod()
{
return "Other method";
}
}
class Derived : Base
{
public override string ToString()
{
return "Derived class";
}
}
class Program
{
static void Main()
{
Derived d = new Derived();
Base b = new Base();
System.Console.WriteLine(b.ToString()); // Base
System.Console.WriteLine(d.ToString()); // Derived class
System.Console.WriteLine((d as Base).ToString()); // Derived class => WHY IS THIS?
System.Console.WriteLine((d as Base).OtherMethod()); // Other method
// System.Console.WriteLine((Base)d.OtherMethod()); // --- prevents compilation
// As noted in the comments, this works
System.Console.WriteLine(((Base)d).OtherMethod()); // Other method
System.Console.ReadLine();
}
}
The only time when a cast to a base-class is required and will result in the execution of a different method is when you have a case of shadowing.
Shadowing occurs when a derived class implements a method of the same name as a method in a base class1 and, explicitly, this is not an override. Usually, these are marked, instead, with the keyword new. If you have an instance of the derived class but wish to invoke the base class member, you need to cast it to that base class (or to any intermediate class in the inheritance chain that doesn't itself shadow the method in question)
In the absence of shadowing, any method invocation always uses the most derived method, based on the runtime type of the object, not the variable's declared type.
Shadowing is usually best avoided, however.
1Not necessarily the direct base class - anywhere within the chain of inheritance back to object.
This can hopefully help: https://msdn.microsoft.com/en-us/library/ms173152.aspx
Base classes may define and implement virtualmethods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. Thus in your source code you can call a method on a base class, and cause a derived class's version of the method to be executed.
In your case you're calling the Object.ToString() virtual method, and the appropriate override is selected during runtime.
That is just how inheritance and polymorphism works in C#. The as operator does a safe cast only, but internally its still a Derived. It just changes it so that the compiler knows it has the right types. With your types, the casting is unnecessary. This just works:
Base d = new Derived();
This will still call the virtual methods overridden by Derived.
As for the explicit cast, its failing because it has a lower precedence than the other operators on that expression. The whole right hand side is evaluated first, then the cast. Essentially, this is what you are telling the compiler.
string result = d.OtherMethod();
Base result2 = (Base)d;

Why can't I call an extension method from a base class of the extended type‏?

I'm trying add the ability to lookup elements in a List<KeyValuePair<string,int>> by overriding the indexer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class MyList : List<KeyValuePair<string, int>>
{
public int this[string key]
{
get
{
return base.Single(item => item.Key == key).Value;
}
}
}
}
For some reason, the compiler is throwing this error:
'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string,int>>' does not contain a definition for 'Single'.
While it is true that List<T> doesn't have that method, it should be visible because it is an extension method from the System.Linq namespace (which is included). Obviously using this.Single resolves the issue, but why is access via base an error?
Section 7.6.8 of the C# spec says
When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct.
Which might seem to preclude access to extension method via base. However it also says
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
If base.I is just like ((B)this).I then it seems like extension methods should be allowed here.
Can anyone explain the apparent contradiction in these two statements?
Consider this situation:
public class Base
{
public void BaseMethod()
{
}
}
public class Sub : Base
{
public void SubMethod()
{
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base) { }
}
Here are some interesting assertions about this code:
I cannot call the extension method using ExtensionMethod() from neither Base nor Sub.
I cannot call base.ExtensionMethod() from Sub.
I can call the extension method using Extensions.ExtensionMethod(this) from both Sub and Base.
I can call the extension method using this.ExtensionMethod() from both Sub and Base.
Why is this?
I don't have a conclusive answer, partly because there might not be one: as you can read in this thread, you have to add this. if you want to call it in the extension method style.
When you're trying to use an extension method from the type it is in (or - consequently - from a type that is derived from the type used in the extension method), the compiler doesn't realize this and will try to call it as a static method without any arguments.
As the answer states: they [the language designers] felt it was not an important use case scenario to support implicit extension methods (to give the beast a name) from within the type because it would encourage extension methods that really should be instance methods and it was considered plain unnecessary.
Now, it is hard to find out what is happening exactly under the covers but from some playing around we can deduce that base.X() does not help us. I can only assume that base.X performs its virtual call as X() and not this.X() from the context of the baseclass.
What do I do when I want to call the extension method of a baseclass from a subclass?
Frankly, I haven't found any truly elegant solution. Consider this scenario:
public class Base
{
protected void BaseMethod()
{
this.ExtensionMethod();
}
}
public class Sub : Base
{
public void SubMethod()
{
// What comes here?
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base)
{
Console.WriteLine ("base");
}
public static void ExtensionMethod(this Sub sub)
{
Console.WriteLine ("sub");
}
}
There are 3 ways (leaving aside reflection) to call the ExtensionMethod(Base) overload:
Calling BaseMethod() which forms a proxy between the subclass and the extensionmethod.
You can use BaseMethod(), base.BaseMethod() and this.BaseMethod() for this since now you're just dealing with a normal instance method which in its turn will invoke the extension method. This is a fairly okay solution since you're not polluting the public API but you also have to provide a separate method to do something that should have been accessible in the context in the first place.
Using the extension method as a static method
You can also use the primitive way of writing an extension method by skipping the syntactic sugar and going straight to what it will be compiled as. Now you can pass in a parameter so the compiler doesn't get all confused. Obviously we'll pass a casted version of the current instance so we're targetting the correct overload:
Extensions.ExtensionMethod((Base) this);
Use the - what should be identical translation - of base.ExtensionMethod()
This is inspired by #Mike z's remark about the language spec which says the following:
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
The spec literally says that base.I will be invoked as ((B) this).I. However in our situation, base.ExtensionMethod(); will throw a compilation error while ((Base) this).ExtensionMethod(); will work perfectly.
It looks like something is wrong either in the documentation or in the compiler but that conclusion should be drawn by someone with deeper knowledge in the matter (paging Dr. Lippert).
Isn't this confusing?
Yes, I would say it is. It kind of feels like a black hole within the C# spec: practically everything works flawlessly but then suddenly you have to jump through some hoops because the compiler doesn't know to inject the current instance in the method call in this scenario.
In fact, intellisense is confused about this situation as well:
We have already determined that that call can never work, yet intellisense believes it might. Also notice how it adds "using PortableClassLibrary" behind the name, indicating that a using directive will be added. This is impossible because the current namespace is in fact PortableClassLibrary. But of course when you actually add that method call:
and everything doesn't work as expected.
Perhaps a conclusion?
The main conclusion is simple: it would have been nice if this niche usage of extension methods would be supported. The main argument for not implementing it was because it would encourage people to write extension methods instead of instance methods.
The obvious problem here is of course that you might not always have access to the base class which makes extension methods a must but by the current implementation it is not possible.
Or, as we've seen, not possibly with the cute syntax.
Try to cast the instance to its base class:
((BaseClass)this).ExtensionMethod()
Applied to your code:
public class Base
{
public void BaseMethod()
{
}
}
public static class BaseExtensions
{
public static void ExtensionMethod(this Base baseObj) { }
}
public class Sub : Base
{
public void SubMethod()
{
( (Base) this).ExtensionMethod();
}
}

In .NET can a class have virtual constructor?

Can a class have virtual constructor??
If yes, why it is required?
no, a class cannot have a virtual constructor.
It doesn't make sense to have a virtual constructor. The order in which objects are constructed in C# is by constructing derived classes first, so the derived constructor is always called since the class you want to call is well known at the time of construction.
The other thing is, if you actually type this code out, you can quickly see that it makes very little sense at all
If you had:
public class BaseClass
{
public virtual BaseClass()
{
}
}
and then
public class InheritedClass : BaseClass
{
//overrides baseclass constructor but why would you do this given that the
//constructor is always going to be called anyway??
public override InheritedClass()
{
}
}
A virtual method is by definition a method which is dispatched based on runtime type analysis of the receiver, not the compile-time static type analysis of the receiver.
A constructor is a method called when a new instance of a particular type is created.
Since the runtime type of a newly created object is always the same (*) as its compile-time type, there is no need for virtual constructors: the runtime dispatch would always choose the same method as the static dispatch, so why bother making a difference?
(*) This is not entirely true; there are scenarios involving COM interop in which the runtime type of a construction is not the compile-time type. Many things are weird in the world of legacy interop code.
Not directly, but the classic Gang of Four pattern Factory Method achieves what would amount to a virtual constructor of sorts, by deferring instantiation to subclasses.
No, how would it work? All constructors in the hierarchy have to be called when you derive child classes from base classes. Making a constructor virtual would imply otherwise.
Something that may be described as having virtual constructor like behaviour, is when you use the factory pattern. Imagine this scenario:
class AnimalFactory
{
virtual Animal CreateAnimal( return new Animal("Cow"); );
}
The default behaviour of this factory is to create cows. But if we create a derived class:
class DogFactory : AnimnalFactory
{
override Animal CreateAnimal( return new Animal("Dog"); );
}
We are now creating dogs. Of course this is not a true virtual constructor (which is impossible), this is virtual construction.
Declaring something virtual means that it can be overridden by a sub-class of the current class. However the constructor is called when a class is instantiated. At that time you can not be creating a subclass of the class in question so there would never be any need to declare a constructor virtual.
If we look at the definitions of the word constructor and virtual we came to a logical conclusion that a constructor can't be virtual.
Just FYI when people are asking for virtual constructors a very good pattern to look into is InversionOfControl
In .NET we have a couple of IoC containers such as ObjectBuilder, Unity, MEF, Spring.NET. In Java (with risk of showing off my Java incompetence) there's Spring, Tapestry and many others.
IMHO IoC is what makes OO deliver on its promises.
For a flexibility of construction an abstract factory can be used. Lets say we have:
class A {}
class B : A {}
with abstract construction:
class AbstractFactoryA
{
abstract A Create();
}
class AbstractFactoryB
{
override A Create() //or B if language support covariant returns
{
...
var result = new B(args)
...
return result;
}
}
and template construction:
class TemplateFactoryA
{
TemplateCreate()
{
...
InternalCreate(args)
...
}
abstract InternalCreate();
}
Constructors execution works in the form of:
ctor()
{
base.ctor()
...
}
but with exact class.
Is there an language that support abstract factory pattern hidden in syntax sugar. It can be very useful. At the end ctor is a method :)

Co-/contravariance support for non-generic types? [duplicate]

This question already has answers here:
Why does C#/CLR not support method override co/contra-variance?
(5 answers)
Closed 8 years ago.
I wonder why the C# team decided not to support co-/contravariance for non-generics, considering they could be just as safe. The question is rather subjective, as I don't expect a team member to respond, but someone may have the insight I (and Barbara Liskov) lack.
Lets look at this sample interface:
public interface ITest
{
object Property
{
get;
}
}
The following implementation will fail, although completely safe (we could always return a more specific type without violating the interface - not in C#, but at least in theory).
public class Test : ITest
{
public string Property
{
get;
}
}
The code would naturally not be safe, if the interface included a setter, but this is no reason for limiting implementation overall, as this could be pointed out by using out/in to declare safety, just as for generics.
The CLR doesn't support covariant return types, whereas it's supported delegate/interface generic variance from .NET 2.0 onwards.
In other words, it's not really up to the C# team, but the CLR team.
As to why the CLR doesn't support normal variance - I'm not sure, other than adding complexity, presumably without the requisite amount of perceived benefit.
EDIT: To counter the point about return type covariance, from section 8.10.4 of the CLI spec, talking about vtable "slots":
For each new member that is marked
"expect existing slot", look to see if
an exact match on kind (i.e., field or
method), name, and signature exists
and use that slot if it is found,
otherwise allocate a new slot.
From partition II, section 9.9:
Specifically, in order to determine
whether a member hides (for static or
instance members) or overrides (for
virtual methods) a member from a base
class or interface, simply substitute
each generic parameter with its
generic argument, and compare the
resulting member signatures.
There is no indication that the comparison is done in a way which allows for variance.
If you believe the CLR does allow for variance, I think that given the evidence above it's up to you to prove it with some appropriate IL.
EDIT: I've just tried it in IL, and it doesn't work. Compile this code:
using System;
public class Base
{
public virtual object Foo()
{
Console.WriteLine("Base.Foo");
return null;
}
}
public class Derived : Base
{
public override object Foo()
{
Console.WriteLine("Derived.Foo");
return null;
}
}
class Test
{
static void Main()
{
Base b = new Derived();
b.Foo();
}
}
Run it, with output:
Derived.Foo
Disassemble it:
ildasm Test.exe /out:Test.il
Edit Derived.Foo to have a return type of "string" instead of "object":
.method public hidebysig virtual instance string Foo() cil managed
Rebuild:
ilasm /OUTPUT:Test.exe Test.il
Rerun it, with output:
Base.Foo
In other words, Derived.Foo no longer overrides Base.Foo as far as the CLR is concerned.
Returned value of method is always "out", they are always on right side of an assignment expression.
CLR Assembly format has metadata which assigns instance methods to interface methods, but this method inference is only dependent on input parameters, they might need to create new format to support, not only that it also becomes ambigious.
New methods mapping algorithm between instance method and interface signature could be complex and CPU intensive as well. And I belive method signatures of interface methods are resolved at compile time. Because at runtime it may be too expensive.
Method inference/resolution could be problem as explained below.
Consider following sample with allowed dynamic method resolution with different return types only (Which is absolutely wrong)
public class Test{
public int DoMethod(){ return 2; }
public string DoMethod() { return "Name"; }
}
Test t;
int n = t.DoMethod(); // 1st method
string txt = t.DoMethod(); // 2nd method
object x = t.DoMethod(); // DOOMED ... which one??
The CLR does not support variance on method overrides, but there is a workaround for interface implementations:
public class Test : ITest
{
public string Property
{
get;
}
object ITest.Property
{
get
{
return Property;
}
}
}
This will achieve the same effect as the covariant override, but can only be used for interfaces and for direct implementations

Categories

Resources