CallByName with different arguments - vb.net

The Function I want to get from CallByName is the following
public PredictionEngine<TSrc, TDst> CreatePredictionEngine<TSrc, TDst>(ITransformer transformer)
Normally I call this function as following:
predEng = CreatePrediction(NewData,NewDataPrediction)(model)
(NewData and NewDataPrediction are classes)
But now Im creating a class dynamically, so I would need to call that function with the new created class.
I have tried every combination but I just can't.
TryCast(CallByName(mlContext.Model, "CreatePredictionEngine", CallType.Method, model), obj.GetType,NewDataPrediction)
(obj is a type of the new class)

Related

Calling method directly without instance variable

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()

Pass an argument to a generic type New constructor in VB.Net Generics

I'm trying to be able to pass a Type parameter to a function called ConvertList, and have that function create some instances of the specified type. So, if I passed in type Foo, the function would create new objects of type Foo and put the created objects into a custom List object (SLMR_OBjList).
The function is in a generic class that is defined:
Public Class BOIS_Collection_Base(Of T)
The function would accept types other than what is passed in the class definition. So, if we create an instance of BOIS_Collection_Base(Of MyTypeA) we may call the function ConvertList(Of MyTypeB).
I want the private variable _convertedList to be of a different type than the class. Is this possible? I can only seem to define it with (Of T).
Here is what I have so far:
Public Class BOIS_Collection_Base(Of T)
Private _convertedList As SLMR_ObjList(Of T) ' I can only seem to define this as (Of T), but want to make sure I can pass in a Type other than the Base(Of T)
Public Function ConvertedObjList(Of myT)() As SLMR_ObjList(Of T) ' Should this be (Of T) or (Of myT) since I want it to use whatever Type is passed in
For Each tempVar In Me.ObjList
Dim newitem As myT = Activator.CreateInstance(GetType(myT), tempVar)
' Next line won't compile, says on newitem 'Value of type 'myT' cannot be converted to 'T'
_convertedList.Add(newitem)
Next
_convertedList.Sort_Direction = Me.Sort_Direction
_convertedList.Sort_Expression_List = Me.Sort_Expression_List
Return _convertedList
End Function
Here is what I would like to be able to do:
Dim mainCollInstance As New BOIS_Collection_Base(Of MyTypeA)
....
'Code that populates the BOIS_Collection_Base.ObjList property with an SLMR_ObjList(Of MyTypeA)
....
' Now I want to take that ObjList, and cast all the items in it to MyTypeB
Dim newListObj As SLMR_ObjList(Of MyTypeB) = mainCollInstance.ConvertList(Of MyTypeB)
Is this possible? Am I going about it wrong?
In response to Plutonix:
If I define _convertedList inside the method, like this:
Public Function ConvertedObjList(Of myT)() As SLMR_ObjList(Of myT)
Dim _convertedList = New SLMR_ObjList(Of myT)
my errors go away, and the method does what I want, but _convertedList is no longer persistant in the object.
If you want to persist the list, then you can't really allow the consuming code to pass a different type for the list each time. That doesn't really make much sense, unless each time it's called, you only want the function to return the portion of the persisted list which contains objects of the given type. If that's the case, then you just need to declare _convertedList As SLMR_ObjList(Of Object) and then filter it and convert it to the correct type as necessary.
If, however, as I suspect is the case, the consumer will always be requesting that it be converted to the same type each time the function is called, then that output type is not really a property of the function call. Rather, it's a property of the whole class. In that case, you should make your class take two generic type arguments, like this:
Public Class BOIS_Collection_Base(Of T, TOut)
Private _convertedList As SLMR_ObjList(Of TOut)
Public Function ConvertedObjList() As SLMR_ObjList(Of TOut)
For Each tempVar As T In Me.ObjList
Dim newitem As TOut = DirectCast(Activator.CreateInstance(GetType(TOut), tempVar), TOut)
' Next line won't compile, says on newitem 'Value of type 'myT' cannot be converted to 'T'
_convertedList.Add(newitem)
Next
_convertedList.Sort_Direction = Me.Sort_Direction
_convertedList.Sort_Expression_List = Me.Sort_Expression_List
Return _convertedList
End Function
End Class
Based on the previous related question and an assumption that MyTypeA and MyTypeB inherit from the same class (never got an answer), you may not need Generics for this. At any rate, this should help with the ctor part of the question. I do not as yet see where Generics fit in since inheritance may do what you want already:
Class MustInherit BiosItem
Public Property Name As String
Public Property TypeCode As String
...
MustOverride Function Foo(args...) As Type
Overridable Property FooBar As String
' etc - the more stuff in the base class the better
End Class
Class TypeA
Inherits ABClass
Public Sub New
MyBase.New ' stuff common to all child types
TypeCode = "A" ' EZ type ID rather than GetType
...
End Sub
End Class
Class TypeB would be the same, but initialize TypeCode to "B". The same for C-Z. These allow you to poll the object rather than needing GetType: If thisObj.TypeCode = "A" Then.... Now, the collection class:
Public Class BIOSItems
Inherits Collection(Of BiosItem)
' inheriting from Collection<T> provides Add, Count, IndexOf for us
' most important the Items collection
'
End Class
Typing the collection as BiosItem will allow TypeA or TypeJ or TypeQ in it. As is, your collection will hold one Type only as it should be. This works because an item which is GetType(TypeA) is also GetType(BiosItem). See also note at the end.
Converting one item to another would seem to be something that would largely be handled by the NEW item being created or converted to. Since they are likely to be very similar then it can be handled by a constructor overload (if they are not similar, well we are well down the wrong road):
' a ctor overload to create the new thing based on the old things props
Public Sub New(oldThing As BiosItem)
MyClass.New ' start with basics like TypeCode, MyBase.New
With BiosItem ' coversion
myFoo = .Foo
myBar = .Bar ' copy common prop vals to self
...
Select Case .TypeCode
Case "B"
myProp1 = .Prop33 ' conversions
myProp3 = .Prop16 + 3.14
...
End Select
' then initialize stuff unique to this type maybe
' based on other props
If .PropX = "FooBar" Then myPropZ = "Ziggy"
End With
End Sub
Code to create, convert, store:
Dim varOldBItem As TypeB = myBiosCol(ndx) ' get old item
Dim varAItem As New TypeA(varOldBItem) ' call the ctor above
myBiosCol.Add(varAItem) ' add new item
myBiosCol.Remove(varoldBItem) ' delete the old if need be
If BOIS_Collection_Base is always supposed to contain MyTypeA, then type it that way (inheriting from Collection<T> still seems in order). If also MyTypeB objects are never added to the collection directly, but converted to MyTypeA first (Edit makes that less clear), then most of the above still applies, except for the inheritance. A ctor overload on MyTypeA could still take an old B object and create itself based on it. I'd be less inclined to do it via the ctor if they do not inherit from the same base class, but it could be done.

InvalidCastException when passing a mocked dependency into a function

I am using Rhino Mocks along with nUnit to attempt to test my function IsApprovable() on an object. The function I am testing relies on another object "UserManager" that needs to be passed in. I am attempting to mock an instance of UserManager so I can specify the result of another function GetApproverDependantsList()
My issue is that when I mock the object and pass it into the function I am testing I get the following InvalidCastException:
Unable to cast object of type 'Castle.Proxies.IUserManagerProxye15b431a53ca4190b7ffbdf5e241e2bb' to type 'MyNamespace.Users.UserManager'.
I am new to this so I am not really sure if I am doing things correctly... Here is the sample mocking code I am using:
Dim helper As New BookingManagerHelper()
Dim booking As Booking = GetDummyBooking() 'method to get a booking in suitable state
Dim parameters As Collection(Of Parameter) = GetDummyParameters() 'factory method, as above
Dim mockedUserManager = MockRepository.GenerateMock(Of Users.IUserManager)()
'I have created a dummy function called GetUserCollectionWithDependant() to create the results I need the mocked function to return...
mockedUserManager.Stub(Function(x) x.GetApproverDependantsList(-1)).[Return](GetUserCollectionWithDependant(1))
'It's the line below where I find my exception...
Assert.AreEqual(True, helper.IsApprovable(booking, mockedUserManager, parameters))
The function I am attempting to test looks like the following:
Public Function IsApprovable(ByVal Booking As Booking , ByVal UserManager As Users.UserManager, Optional ByVal Parameters As Collection(Of Parameter) = Nothing) As Boolean
'various logic checks are performed on the objects passed in
End Function
Some things to note:
UserManager implements the interface IUserManager
UserManager contains additional properties and functions that are not defined by the interface
UserManager also inherits from a base class (do I need to override base properties?)
I can post more code if needed. Thanks in advance.
I am no expert in VB.NET but IsApprovable expects a UserManager instance. The mock is of type IUserManager. Maybe you want to adjust IsApprovable to use a IUserManager instance.

MyBase can not to be used in a Extension Method?

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.

Issue with passing parameters by reference into public shared methods

I have a List(Of AddlInfo) with AddlInfo being an object.
I'm trying to pass addlInfoList by reference into a function of another class:
Public Shared Sub SortAddlInfo(ByRef addlInfoList As List(Of AddlInfo))
addlInfoList.Sort(AddressOf Comparer)
End Sub
Private Function Comparer(ByVal x As AddlInfo, ByVal y As AddlInfo) As Integer
Dim result As Integer = x.AddlInfoType.CompareTo(y.AddlInfoType)
Return result
End Function
This works if I'm not passing the reference into another class, but when I try to do this, I get the following error:
Overload resolution failed because no accessible 'Sort' can be called with these arguments:
'Public Sub Sort(comparison As System.Comparison(Of AddlInfo))': Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.
'Public Sub Sort(comparer As System.Collections.Generic.IComparer(Of AddlInfo))': 'AddressOf' expression cannot be converted to 'System.Collections.Generic.IComparer(Of MyProject.AddlInfo)' because 'System.Collections.Generic.IComparer(Of MyProject.AddlInfo)' is not a delegate type.
I could put the methods back into the calling class, but I'd like to be able to call these methods from different classes within my application.
I could also instantiate a fresh List in the methods, but why? Seems silly.
Any way around this? (Or do I need to explain more?)
Thanks in advance!
Try putting your compare function into a class that implements IComparer.