Using interface function defined in DLL - vb.net

I'm using an interface defined in a DLL.
When I call...
m.GetMasterVolumeLevelScalar(btVol)
... I get a Null Reference Exception because "m" is nothing.
However, I can't use "new" on this interface.
How would I use this interface correctly?
I did read on implements, but I didn't find an example similar to this interface.
Thank you.
Edit: I know now that I need to type
Implements Vannatech.CoreAudio.Interfaces.IAudioEndpointVolume
and the functions will automatically be added to my class.
However, I'm not sure what to do with the NonImplementedException for example here:
Public Function GetMasterVolumeLevelScalar(ByRef level As Single) As Integer Implements IAudioEndpointVolume.GetMasterVolumeLevelScalar
Throw New NotImplementedException()
End Function

I got it:
I simply need to type
Implements Vannatech.CoreAudio.Interfaces.IAudioEndpointVolume
By doing that, all functions will automatically be added to the class in which I typed this.
I just didn't scroll down enough to see that.

Related

best matching overloaded method is not being called

I have the following methods:
Public Function RenderRateTable() As String
Private Function RenderRateTable(ToddVersionedObject As ToddVersionedObject,
FieldInfo As FieldInfo) As String
Private Function RenderRateTable(ArrayIndexes As List(Of ArrayIndexesAttribute.ArrayIndex),
ThreeDimensionalArray As ThreeDimensionalDecimalArrayType) As String
Private Function RenderRateTable(ArrayIndexes As List(Of ArrayIndexesAttribute.ArrayIndex),
TwoDimensionalArray As ArrayOfDecimalArraysType) As String
Note that the types that I'm overloading (ArrayOfDecimalArraysType, ThreeDimensionalDecimalArrayType) are not classes that inherit from the same base class. They are different structures that don't inherit from anything. They were written by someone else and I can't change them.
When I call it from within the same class like this
Dim MyThreeDimensionalDecimalArrayType As ThreeDimensionalDecimalArrayType
RenderRateTable(MyArrayIndexes, CType(MyThreeDimensionalDecimalArrayType, Object))
it doesn't go to the right method. It just goes to RenderRateTable().
What's even stranger is, the call is made with two arguments (parameters), but these are (ignored?) and it calls a method that takes no parameters and no run-time error is thrown!
I have Option Strict Off and the variable I'm passing to the parameter ThreeDimensionalArray is of type Object.
I'm trying to get it to where I have a bunch of overloads and it picks the right method based on the type of the Object passed.
Polymorphic method calling instead of an Select Case statement. I hate conditional blocks like that.
UPDATE
I got the code working by declaring the overloads Public, but I still don't understand:
Why the dispatcher wouldn't find the right Private method when the
call is within the same class.
Why the dispatcher would call a method with no parameters when the call is made with 2 parameters, and not throw an error.
You have RenderRateTable() as Public and the rest as Private, which will prevent it from being able to use the correct overload when called from outside the class.
It is very likely that Option Strict On would have pointed out that as a problem: I recommend that you use it to make your programming endeavours easier :)

Compiler doesn't see CompareTo method in IComparable(Of T) object

I'm trying to apply the answer to Implementing generic IComparer in VB to my project by implementing an IComparable interface for a class in VB.NET. The section for the GenericComparer in that answer compiles fine, but the IComparable interface on my specific object won't get past the compiler.
Public Class RowAndRanking
Implements IComparable(Of RowAndRanking)
Public html As String
Public rank As Double
Public Function CompareTo(other As RowAndRanking) As Integer
Return Math.Round(Me.rank - other.rank)
End Function
End Class
The compiler keeps insisting that "Class 'RowAndRanking' must implement 'Function CompareTo(other As RowAndRanking) As Integer' for interface 'System.IComparable(Of RowAndRanking)'.", but looking at my code, I can see that method signature. Furthermore, if I go to where I'm trying to run a Sort on a List of these objects, I can type:
Dim row as RowAndRanking = new RowAndRanking
row.CompareTo(...
And Visual Studio's code complete picks up the method signature.
I've tried cleaning and rebuilding the project, but the issue remains. I've tried changing it to use a non-generic comparer solution, but the compiler still doesn't see the CompareTo method. This should be simple, but the compiler just doesn't see the function. Has this happened to anyone else? Is there something else that I can try?
Unlike C#, VB requires that you explicitly mark implementing methods.
Add
Implements IComparable(Of RowAndRanking).CompareTo

How to implement an interface in VB.Net when two methods have the same name but different parameters

I am a C# programmer but I have to work with some VB.Net code and I came across a situation where I have two methods on an interface with the same name but different method parameters. When I attempt to implement this interface in a class, VB.Net requires explicitly declaring "Implements MethodName" after the method signature. Since both method names are identical, this is confusing the compiler. Is there a way to get around this sort of problem? I suspect this must be a common occurrence. Any thoughts?
N.B. This was more a case of the programmer not verifying that the interface in question had not changed from underneath him.
How is this confusing the compiler?
The compiler expects to find an implementation for every method signature, and distinguishes the implementations by their signatures.
If the signatures are identical/undistinguishable (in most cases it means that the arguments are of the same types in the same order) you'll get a design-time error related to the interface, saying that the two methods cannot overload eachother as they have the same signature.
So, in any case, the compiler should not be confused.
Should you need further assistance, please attach a code sample - these things are relatively easy to resolve.
Tip: When writing the implementation, as soon as you write down "implements MyInterface" and hit Enter - Visual Studio will create a "skeleton" code of the implementation, which saves you writing the method signatures and correlating them to the interface.
Example code of having two methods with the same name and everythign working well:
Interface MyInterface
Sub MySub(ByVal arg0 As DateTime)
Sub MySub(ByVal arg0 As ULong)
End Interface
Class MyImplementation
Implements MyInterface
Public Sub MySub(ByVal arg0 As Date) Implements MyInterface.MySub
...
End Sub
Public Sub MySub(ByVal arg0 As ULong) Implements MyInterface.MySub
...
End Sub
End Class
You can make the method private and give it another name.
Like:
Private Sub SaveImpl(ByVal someEntity As IEntity) Implements IRepository.Save
this will look to the outside like: someRepository.Save

Can I qualify the type of a parameter in VB.NET?

This is kind of two questions (one more specific than the other).
If I have a method like this:
Public Function Blah(String Foo)
End Function
Can I qualify Foo against another type (for instance can I require that Foo be a String that also implements IInterface?).
I'm imagining something vaguely similar to this:
Public Function Blah(RandomObject Foo Where RandomObject Is IInterface)
End Function
Additionally, is there any way to qualify the Type parameter?
For instance, can I require that the Type I take as a parameter is of a particular class tree?
Public Function Blah(Type t Where Type Of String)
End Function
I should mention that I am using this in the context of a property of an attribute so the class declaration itself cannot be generic (this is purely focused on qualifying a method parameter rather than typing a class and its methods).
This looks like a case for generics to me. Your method signature would be something like this in VB.NET:
Public Function Blah(Of T As {IImplementedByT})(Foo As T)
This specifies that Foo can be of any type T as long as T implements IImplementedByT. Note that this method can be generic without the containing class needing to be generic. If you want T to be a class derived from RandomClass that also implements this interface, you can specify both constraints:
Public Function Blah(Of T As {RandomClass, IImplementedByT})(Foo As T)
You can do the first for a generic type, but not for a nongeneric type. Basically a variable (including a parameter) can only have one compile-time type, so you can't say "it has to be a Foo and an IBar - you have to pick one or the other. Generics let you say "it has to be some type T where T derives from Foo and implements IBar" though.
Generics is a huge topic - too big to cover in a Stack Overflow answer - but Microsoft has a good introductory article.
As for your second question - no, you can't do that. The Type value will only be known at execution time, so it has to be an execution time check. You can write that check fairly easily though, with Type.IsAssignableFrom.
Not sure what you mean by "Foo be a String that also implements IInterface".
string class is sealed, so you can't inherit from it & hence you cant implement an interface on top of it.
I hope I am on the right page.

How do I treat two similar types as one?

In VB.NET, I am trying to talk to a webservice (that can't be changed) to create and update customer data.
The CreateCustomer service expects an object of type ConsumerPerson and the ChangeCustomer service expects an object of type ChangeData.
The properties of these two object are exactly the same, so I thought it would be wise to just set the properties using one single function.
However, I am unable to find a way to tell my function that I want to fill either the ConsumerPerson or the ChangeCustomer object.
How do I make this work without late binding problems?
An interface sounds like your best approach. Here is a short code snippet. I picked a simple property named "Name" of type string. It should be easy to modify with the actual properties on your class.
Public Interface ICustomerData
ReadOnly Property Name As String
End Interface
Public Class ConsumerPerson
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
Public Class ChangeData
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
use an interface !
declare an interface IFoo, and implement its members in your subclasses ConsumerPerson and ChangeCustomer. That's exactly what interfaces are for.
You create an interface which both classes implements.
Is it not possible to overload your function with the second data type?
If you cannot change your objects, but they share the same field names, you could xml serialize the data and deserialize as the other class. - You should strongly consider the performance implications of this; however, it would give you the functionality you're asking for.