I created a module to add some Extension Methods to a Class.
This Class inherits from another parent Class.
In the code of my Extension Methods, I would like to refer to the base Class using MyBase.
This doesn't seems to be allowed (Error message : "'MyBase' is not valid within a Module.")
<Extension()>
Public Function Get_OutOfSpace(val as ClassA) As Boolean
Return MyBase.IsOutOfSpace()
End Function
How can I invoke a method of my base class within an Extension Method?
That's why they force you to write extension methods in a module, so you can't make the mistake of using MyBase. But there's at least one other thing wrong with your code, you didn't extend anything. The first argument of an extension method must be a reference to the object, of the type you want to extend:
<Extension()>
Public Function Get_OutOfSpace(ByVal obj As Foo) As Boolean
''...
End Function
So a likely implementation is Return obj.IsOutOfSpace. Which in turn makes it very likely that you don't actually have any use at all for this extension method since the class you want to extend already has an IsOutOfSpace property.
Only use extension methods to add methods to classes. And only do so if you can't change the class.
Related
Is using the Named Constructor Idiom possible in VB.NET? I've found many examples in C#/C++ but can't quite wrap my head around how to use it in vb.net. Seems like a better method of keeping my code readable when involving a lot of constructors with similar argument types.
I've never heard this term before, but after a quick search it sounds vaguely like the Static Factory Pattern. The idea is you make the constructor private and use a shared (static in c#) public function to create the new object.
Public Class Foo
Private Sub New()
End Sub
Public Shared Function CreateNew(param as Object) as Foo
Dim obj as New Foo()
obj.Prop = param
return obj
End Function
End Class
You sure can make Named Constructors in VB. The pattern uses a static (Shared in VB) factory method on the class itself, so that the method can be named. (Other Factory patterns involve using a separate Factory class to provide the static method.)
System.Drawing.Color is a simple example. The pattern is implemented underneath as a static (Shared) property. Since no arguments are necessary, the Get method of a Property works just fine:
Public Shared ReadOnly Property Chartreuse As Color
Usage:
Dim favoriteColor as Color = Color.Chartreuse
Or you can make static factory methods to do the same thing.
Public Class TheClass
Public Sub New()
End Sub
Public Sub New(input As String)
'do something with input
End Sub
Public Shared Function MyNamedConstructor() As TheClass
Return New TheClass
End Function
Public Shared Function AnotherNamedConstructor() As TheClass
Return New TheClass("Another Name")
End Function
End Class
As for whether this pattern is "better" than overloading constructors, that's really an opinion. Personally, I would just overload the constructors. As you can see in the example above, the constructors need to be there anyway.
I suggest using the Named Constructor pattern when you have only a few possible ways to construct your class/struct, but consumers of your class/struct will be using those few constructors often, and with different input values to those constructors (as in the System.Drawing.Color example).
The Name in 'Named Constructor' doesn't represent a name for the constructor itself, but for the object resulting from the constructor. If your named constructor can be used to create two objects that don't feel right to give the same name to, then don't give the constructor that name.
I have a hard time to either figure out the correct interface or actual implementation signature/syntax for a method. The method itself works as expected, the compiler at least doesn't complain about the interface's syntax, but when actually adding the necessary Implements statement to the method, it fails.
Here's what I have:
Public Interface IMyInterface
Function GetIt(Of T As Class)() As T
End Interface
Public Class Foo
Implements IMyInterFace
Public Function GetIt(Of T As Class)() As T
End Class
If I now try to add the necessary Implements statement, even using autocompletion from the IntelliSense popup, VS complains about the syntax. Without the Implements statement, VS complains:
BC30149 Class 'Foo' must implement 'Function GetIt(Of T As
Class)() As T' for interface 'IMyInterface'.
First, doing so by using autocompletion ends up with the following incomplete line:
Public Function GetIt(Of T As Class)() As T Implements IMyInterface.GetIt(Of
VS obviously complains about a)
'Type expected'
and b)
')' expected
Second, upon completing that line with
Public Function GetIt(Of T As Class)() As T Implements IMyInterface.GetIt(T As class) As T
VS still reports
')' expected
and points to the 'A' in the parameter definition 'As Class'.
So what's the right syntax for this kind of method signature?
You're both correct, the solution is
Public Function GetIt(Of T As Class)() As T Implements IMyInterface.GetIt
I also had the idea of letting VS do the refactoring (Edit -> Refactor -> Extract Interface) and the above is what VS did that way. I still find it strange that VS (2017)'s autocompletion yields a different result.
MyClass is a keyword, so you can't name the class that.
You can close keywords in square brackets in VB.NET to avoid that.
Public Interface IMyInterface
Function GetIt(Of T As Class)() As T
End Interface
Public Class [MyClass]
Implements IMyInterface
Public Function GetIt(Of T As Class)() As T Implements IMyInterface.GetIt
Throw New NotImplementedException()
End Function
End Class
But since this is just a proof of concept, your actual implementation probably won't suffer from this issue.
By the way, I'm voting to close your question because it's more of a question about using MyClass as a class name. If you hadn't done that your auto-complete surely would have generated the proper method signature. Instead your IDE was getting confused by the misplaced keyword. I hope this helped you solve your problem
Is there a way to call directly a method without creating instance of specific class like it is in C# so apart from that way:
Dim myclass as New ClassX
myclass.MyMethod()
is there a way to use soemthing like:
New ClassX.MyMethod
i found this way and seems to be working but not sure if its correct:
(New ClassX).MyMethod
If your method is an instance-level method you can only access it by using an instance of the class. By using
(New ClassX).MyMethod
you implicitly create a new instance that you access only once.
An alternative is to change the method's signature and mark it as a Shared method:
Public Class ClassX
Public Shared Sub MyMethod()
' ...
End Sub
End Class
Shared is the VB.NET way of creating a static method as it is called in C#. This way, you can access the method by only specifying the class name without creating an instance:
ClassX.MyMethod()
I have a few dozen classes which all implement the same interface and many of the methods have identical implementation. I have to do a lot of copy and paste whenever I add a new class. How can I get less code duplication?
I've heard that you should put the common code in a helper class but a lot of these methods are really trivial so calling a helper method is barely any simpler than doing the actual work.
Inheritance would save re-declaring all these methods but it would make it messy for the few classes that don't have the identical implementation.
Examples:
Identical in nearly every class...
Public Sub ThingWasDeleted(ByVal deletedThing As Thing) Implements Iinterface.ThingWasDeleted
If MyThing Is deletedThing Then
MyThing = Nothing
End If
End Sub
...but occasionally different:
Public Sub ThingWasDeleted(ByVal deletedThing As Thing) Implements IInterface.ThingWasDeleted
'Do nothing
End Sub
Identical in every class but already just as simple as calling a common helper method:
Public ReadOnly Property DisplayName() As String Implements IInterface.DisplayName
Get
Return DisplayNameShared
End Get
End Property
If you put these methods in a helper class, wouldn't that make it just as messy (if not more) than having an abstract base class where you can override the base class's functionality when needed?
For example:
Public MustInherit Class BaseClass
Public ReadOnly Property DisplayName() As String
Get
Return DisplayNameShared
End Get
End Property
Public Overridable Sub ThingWasDeleted(ByVal deletedThing As Thing)
If MyThing Is deletedThing Then
MyThing = Nothing
End If
End Sub
End Class
This provide a definition of the property that all inheriting classes can use, and gives the inheriting class an option to override and create their own implementation of ThingWasDeleted.
For example:
Public Class MyClass
Inherits BaseClass
Public Overrides Sub ThingWasDeleted(ByVal deletedThing As Thing)
' Do nothing
End Sub
End Class
On the other hand, if you wrote a helper class, you'd have to define every method, and the developer (which may or may not be you) would have to know which method to change. Additionally, instead of having the option to use the existing functionality in the base (abstract) class, every class you create will have to call each of the proper helper methods.
Personally, I prefer the former option, mainly because the inheriting classes don't have to call anything to get the base functionality established in the base class, and can override what they need to on a case-by-case basis. Conversely, having them all in a helper class means you have to at least write the code to call each of the necessary helper methods in every class you have.
I have a groovy class that looks up a method reference and then invokes it. The method being invoked is a private method. When the actual class is an instance of the child class, it throws an error that it cannot find the private method, even though it is the public method in the parent that actually calls it.
In this case, I could obviously just call pMethod2() directly and that works, but I'm trying to understand why this doesn't work as written and if there's a way to correct it so it works.
class Parent {
def pMethod1() {
def m = this.&pMethod2
m() // this call fails if the calling class is of type Child
}
private def pMethod2() {}
public static void main(String[] args) {
new Child().pMethod1();
}
}
class Child extends Parent {}
It is a bit confusing, especially if you're used to C / C++. What you get when using the ".&" operator in Groovy is not an address, but an instance of MethodClosure.
The MethodClosure object contains an owner and a delegate object, which is used when resolving the method to call. In your example, the owner and delegate object will be "this", which is an instance of Child. The method to call is simply stored as a string.
So, the assignment
m = this.&pMethod2
is just a shorthand way of writing
m = new MethodClosure(this, "pMethod2")
When you invoke the m() closure, it will try to resolve (at runtime) the method by looking for methods named "pMethod2" in the owner and the delegate objects respectively. Since the owner and delegate is an instance of Child, it will not find private methods located in Parent.
To make your example work you must make sure that the method is visible to the owner and/or delegate of the closure.
This can be done several ways, for instance by changing the access modifier of pMethod2 to protected, or by creating the closure with an instance of Parent; something like this:
m = new Parent().&pMethod2
Note that is is irrelevant that you created the MethodClosure instance in a method where pMethod2 is actually visible. It is also irrelevant that you invoke the closure in a method where it is visible. The method is not visible to the owner or delegate of the MethodClosure, which is what is being used when resolving the method.