.NET Forum / .NET Framework / New Users / January 2007
VB vs. C# language challenge question
|
|
Thread rating:  |
Tomasz Jastrzebski - 28 Nov 2006 23:23 GMT Hello,
Below are to equivalent(?) pieces of C# and VB.Net code While the C# version compiles with no warning, the VB.Net version does not compile due to the compiler error BC30149: Class 'c2' must implement 'Sub m1()' for interface 'i1'.
Does it mean that in VB interface must be implemented, even if it is already non-explicitly implemented in the base class c1?
How to make this VB code compile *without altering the c1 class* ? - that is the constraint! I can not get it compile in VB, while in C# it is just a piece of cake.
Motivation: I want to access base class methods by interface specified in a derived class. As strange as it sounds, in C# it works just as expected - test yourself: i1 c = new c2(); c.m1();
Thank you,
Tomasz
// C# version class c1 { public virtual void m1() { } }
class c2 : c1, i1 { }
public interface i1 { void m1(); }
' VB version Class c1 Public Overridable Sub m1() End Sub End Class
Class c2 Inherits c1 Implements i1 End Class
Public Interface i1 Sub m1() End Interface
Kevin Yu [MSFT] - 29 Nov 2006 03:18 GMT Hi Tomasz,
This is a good question. In fact, it is the difference between C# and VB.NET compilers.
In C#, when you fail to implement an interface, the compiler will automatically look for a method with the same name as the method in the interface and map it to the method implementation. In this case, since there is an m1() method in c1, it will use this method to implement i1.m1().
However, this is not available in VB.NET compiler. That's why a compile error is generated.
If anything is unclear, please feel free to let me know.
Kevin Yu Microsoft Online Community Support
================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ==================================================
(This posting is provided "AS IS", with no warranties, and confers no rights.)
Michael D. Ober - 29 Nov 2006 14:49 GMT This is actually one of the places where the VB compiler gets it right. Once you turn on Option Strict and Option Explicit, it makes a lot fewer assumptions about the code and forces cleaner code. The question you need to ask yourself is "will the C# compiler always guess right?" The answer is obviously "no", so having the compiler report an error is actually better for correctness.
Mike Ober.
> Hi Tomasz, > [quoted text clipped - 34 lines] > (This posting is provided "AS IS", with no warranties, and confers no > rights.) Tomasz Jastrzebski - 29 Nov 2006 19:46 GMT Well, I see your point. However, lack of this feature, prevents me from implementing some very important functionality, so I really do not see it as advantage. I wish I could write code in C# but it is against our standards.
Tomasz
> This is actually one of the places where the VB compiler gets it right. > Once you turn on Option Strict and Option Explicit, it makes a lot fewer [quoted text clipped - 45 lines] >> (This posting is provided "AS IS", with no warranties, and confers no >> rights.) Michael D. Ober - 29 Nov 2006 20:19 GMT Instead of using an interface, can you make the interface protected so you have the option? If you want the base implementation, don't do anything. If you want to use a different implementation in the derived class, shadow the base, calling the base with mybase.m1() if you need to.
Also, you might want to post this question in news:microsoft.public.dotnet.languages.vb.
Mike Ober.
> Well, I see your point. However, lack of this feature, prevents me from > implementing some very important functionality, so I really do not see it [quoted text clipped - 56 lines] >>> (This posting is provided "AS IS", with no warranties, and confers no >>> rights.) Tomasz Jastrzebski - 29 Nov 2006 22:12 GMT Protected interface? I am not sure I understand. Could you show modifying my example accordingly?
Tomasz
> Instead of using an interface, can you make the interface protected so you > have the option? If you want the base implementation, don't do anything. [quoted text clipped - 66 lines] >>>> (This posting is provided "AS IS", with no warranties, and confers no >>>> rights.) Jon Skeet [C# MVP] - 29 Nov 2006 22:44 GMT > This is actually one of the places where the VB compiler gets it right. > Once you turn on Option Strict and Option Explicit, it makes a lot fewer > assumptions about the code and forces cleaner code. The question you need > to ask yourself is "will the C# compiler always guess right?" The answer is > obviously "no", so having the compiler report an error is actually better > for correctness. In what way is the C# compiler "guessing"? Not only does the name have to match, but the method signature does too. I don't see how that counts as guesswork. I wouldn't *hugely* object to C# behaving the same way that VB.NET does, but I wouldn't say that the C# team got it wrong in this case.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Michael D. Ober - 30 Nov 2006 05:20 GMT The problem is one of verifiable correctness. In this particular case, the C# compiler allows a "default" implementation that may not always be correct for the derived class. If the default implementation is correct for the defined class, then there is no need for an interface definition. If not, not having the compiler catch this can lead to disaster. This is an error of omission.
The VB compiler, on the other hand, takes the opposite tack. It forces you to implement the interface in the derived class. If the default implementation is correct for the derived class, you simply call it from the derived class using mybase.defaultmethod(args). The one thing that the VB IDE does that is useful, but that can lead to the same error of omission that C# compiler allows is that the VB IDE default configuration is to actually insert the function prototype for you, but it doesn't put any code inside the function that would cause the compiler to report a compilation error, thus allowing the compiler to compile clean but your code not run properly.
Mike Ober.
> > This is actually one of the places where the VB compiler gets it right. > > Once you turn on Option Strict and Option Explicit, it makes a lot fewer [quoted text clipped - 8 lines] > way that VB.NET does, but I wouldn't say that the C# team got it wrong > in this case. Jon Skeet [C# MVP] - 30 Nov 2006 19:12 GMT > The problem is one of verifiable correctness. In this particular case, the > C# compiler allows a "default" implementation that may not always be correct > for the derived class. If the default implementation is correct for the > defined class, then there is no need for an interface definition. If not, > not having the compiler catch this can lead to disaster. This is an error > of omission. It's an error I've never been bitten by, nor have I heard of anyone else being bitten by it, I have to say. It's also perfectly possible to have the same error of omission if you only decide to implement the interface later on, having already implemented methods which happen to have the same name.
To *really* prevent this from being a problem, you'd have to force every interface method implementation to explicitly say that it was implementing the interface, and not just there as a normal part of the class.
It also makes logical sense for base class methods to "count", as it were - if you regard an interface as a contract, the class is already implementing the contract.
> The VB compiler, on the other hand, takes the opposite tack. It forces you > to implement the interface in the derived class. If the default > implementation is correct for the derived class, you simply call it from the > derived class using mybase.defaultmethod(args). Which would, to me, look pretty odd. It's also a pain if the method implementation is sealed.
> The one thing that the VB > IDE does that is useful, but that can lead to the same error of omission [quoted text clipped - 3 lines] > error, thus allowing the compiler to compile clean but your code not run > properly. That's where unit tests are important, of course :)
Overall, I think I still prefer the C# way of looking at things.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Tomasz Jastrzebski - 29 Nov 2006 19:49 GMT Thank you Kevin. That is what I thought, but I was hoping there was any way around it. Well, I wish I could program in C#.
Tomasz
Kevin Yu [MSFT] - 01 Dec 2006 07:22 GMT Hi Tomasz,
I'm afraid there is no workaround to it. Because this is by design in the compilers. I'm sorry for the inconvenience.
Kevin Yu Microsoft Online Community Support ==================================================
(This posting is provided "AS IS", with no warranties, and confers no rights.)
Michael D. Ober - 30 Nov 2006 05:20 GMT The VB conversion is:
'// C# version ' class c1 { ' public virtual void m1() { ' } ' }
' class c2 : c1, i1 { ' }
' public interface i1 { ' void m1(); ' }
' VB version Class c1 Public Overridable Sub m1() End Sub End Class
Class c2 Inherits c1 Implements i1
Public Sub m11() Implements i1.m1 MyBase.m1() End Sub
End Class
Public Interface i1 Sub m1() End Interface
The real problem with this is that in VB, interfaces cannot contain default code. If it needs to, I would implement the classes as follows:
Class c1 Public Overridable Sub m1() ' Default implementation of m1 End Sub End Class
Class c2 Inherits c1
' To hide the underlying m1 implementation ' Public Shadows Sub m1() ' End Sub
' To extend the underlying my implementation. ' Public Overrides Sub m1() ' End Sub End Class
Mike.
> Hello, > [quoted text clipped - 46 lines] > Sub m1() > End Interface Steven Spencer (Spinalogic) - 31 Jan 2007 05:49 GMT Forgive me if this doesn't quite seem relevant here, but in java there is the concept of an Abstract class. This is where some methods are implemented and others are left "abstract" much like the interface so that you can inherit the abstract class yet still need to implement some methods upon it. Is this feature not possible in .net? or do you need to create a base class to overload and then a separate interface with the undefined methods?
> The VB conversion is: > [quoted text clipped - 110 lines] >> Sub m1() >> End Interface Kevin Spencer - 31 Jan 2007 13:24 GMT Yes, in C# it is called "Abstract". In VB it is called "MustInherit".
 Signature HTH,
Kevin Spencer Microsoft MVP Software Composer http://unclechutney.blogspot.com
The shortest distance between 2 points is a curve.
> Forgive me if this doesn't quite seem relevant here, but in java there is > the concept of an Abstract class. This is where some methods are [quoted text clipped - 122 lines] >>> Sub m1() >>> End Interface
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|