Thursday, January 20, 2005

Technical mumbo jumbo

Thought will write a small note about few things about .net which are not too obvious.
a) Difference between new and virtual methods:
We all know that new keyword(Shadows in VB.Net) is used to obscure a base method implementaion which is not declared as virtual. This particular functionality is particularly useful when you are inheriting a "third-party" library's class where the original developer didn't find it necessary to declare the method as virtual (Aside: Another flame say we are building a class library which can be used/extended by any set of developers shall we make all possible methods virtual or only those methods which we "think" might need to be overridden: I think it should be the latter). Given the "power" of new why does one have to declare his method virtual when anyway the inheriting class can obscure the base implementation whenever he needs to? Let's take a look at a sample code around new keyword:

class Base
{
public string A()
{
return "base";
}
}

class Child : Base
{
public new string A()
{
return "child";
}
}

public static void Main()
{
Base b = new Child();
Console.WriteLine(b.A());
}

Any OO guy would tell you that in the above code Child's A() should be invoked but that's what sets new apart from virtual. Which particular implementation is invoked in case of new is totally dependent on the variable type and not on the instance type (unlike virtual methods), since the variable type is of Base class, Base.A() would be invoked and "base" would be printed. As you can see "new" breaks a lotsa OO rules so my advice would be to use it only where it is absolutely necessary and perhaps usage of new in an application signifies a bad design.

b) Implementing multiple interfaces:
Another code snippet:
interface I1
{
string A();
}

interface I2
{
string A();
}

class Concrete : I1, I2
{
public string A()
{
return "A()";
}
}

public static void Main(){
I1 i1 = new Concrete();
Console.WriteLine(i1.A);
I2 i2 = new Concrete();
Console.WriteLine(i2.A);
}

Since C# allows implementing multiple interfaces which both define a method with same signature I need to only implement it only once and in both the above case "A()" would be printed. But what if I want different implementation for the A() declared in the two disparate interfaces? Here's how to do it:
class Concrete : I1, I2
{
string I1.A()
{
return "I1.A()";
}
string I2.A(){
return "I2.A()";
}
}

Another thing that never struck my mind was that there is one more way of making a non-inheritable class instead of using the keyword "sealed"...just make the ctor private, the only problem with this approach being that also means that no one can do a "new" on this class, stilll wondering though why would not want to use "sealed" keyword in such a scenario.

1 comment:

  1. Nice one again. Subtle, yet important difference.

    Best Wishes,
    aviNash

    ReplyDelete