Protected Overridable properties in NotInheritable classes in VB.NET
I noticed that Jason posted up some code that we were discussion regarding some weirdness in some code I was converting from C# to VB.NET. For the specifics of the problem, check out his blog. After the fact, Paul Vick confirmed that it was indeed a bug (both to Jason and I via email) and will be fixed in VB 2K5. However, until then, I found a couple of workarounds.
Workaround #1 (credit Paul Vick)
Remove the derived classes NotInheritable
access modifier. Although this would allow someone to inherit from your derived class, it’s probably the safest workaround if you don’t have access to the base class implementation or if your properties are read/write. For some reason, this one didn’t even enter into my head since I was focused on trying to keep the access levels the same between the VB and C# implementations.
Workaround #2:
Change the base class implementation from a ReadOnly Property
to a Function
of the same name.
1
2
3
Protected Overridable Function IntegerData() As Integer
Return 42
End Function
And in the derived class:
1
2
3
Protected Overrides Function IntegerData() As Integer
Return 44
End Property
The second workaround is great if you have access to the base class’ source and you are replacing a ReadOnly
property. If you don’t, you can use workaround #1.
Workaround #3:
Change the Protected Overrides
property in the derived class to be a Private Shadows
property.
1
2
3
4
5
Private Shadows ReadOnly Property IntegerData() As Integer
Get
Return 44
End Get
End Property
UPDATE: However, this workaround is not recommended. Although it will give you a similar access level as
Protected Overrides
and removes the error, the access levels are not identical. “If you were to cast an instance of the derived class to the base class, all of a sudden you’d be calling the base implementation again which is not the intent.” (Paul Vick) I didn’t even think of that. I suppose you could get away with this as long as you understand the implications and make sure your coding takes those into account. I had to mention it since it’s one of the things I found that appeared to be a solution in my experimentation.
The issue is related to the fact that a NotInheritable
class can’t have Protected
members/methods; since Protected
defines that the current and derived classes has access to those signatures. There is a check in the compiler that will allow an exception the rule. If it’s an overridden signature, it allows those to be marked as Protected
(since the signatures must match the base class signatures); however only for methods, not properties; and there’s the bug.
Workaround #2 is what I ended up using in the strongly-typed ArrayList
template I’m doing in CodeSmith; which as a property, even in the original C# code, FxCop barks since properties shouldn’t return arrays. So moving it to a function removes that message as well. Another point concerning shadowing, FxCop seems to bark at you for anything that is shadowed.