Compiler doesn't see CompareTo method in IComparable(Of T) object - vb.net

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

Related

Using interface function defined in DLL

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.

BinarySearch - Failed to compare two elements in the array

So we recently migrated an application from .NET 1.1 to .NET 4.0.
And with that, there was a bunch of compatibility issues which we had to fix.
One of them is that a block of code is throwing the InvalidOperationException.
Public Function MyFunction(ByVal Params As myParams, ByVal ParamArray someNumber As Integer()) As myData
...
If someNumber.BinarySearch(options, MyEnum.Something) >= 0 Then
...
EndIf
...
EndFunction
Before we migrated to .NET4 this was working correctly in .NET1. Now based on some threads i've been reading, there has been reports about this problem which was fixed in .NET4.5. And that to fix this in my current version, I have to implement the IComparable interface on all elements of the array.
How do I go about to fixing this? I would appreciate any help and pointer. Thanks!
EDIT: Adding the link to the BinarySearch method we are using in the code. https://msdn.microsoft.com/en-us/library/y15ef976.aspx
Add Implements IComparable IComparable Interface to your class definition. 2. Add a method for IComparable.CompareTo to the class. Borrowing from msdn:
Public Class Temperature
Implements IComparable
' The temperature value
Protected temperatureF As Double
Public Overloads Function CompareTo(ByVal obj As Object) As Integer _
Implements IComparable.CompareTo
If obj Is Nothing Then Return 1
Dim otherTemperature As Temperature = TryCast(obj, Temperature)
If otherTemperature IsNot Nothing Then
Return Me.temperatureF.CompareTo(otherTemperature.temperatureF)
Else
Throw New ArgumentException("Object is not a Temperature")
End If
End Function
....
End Class
Of coarse the code in the CompareTo function depends on your class (you didn't provide much to go on). All numeric types (such as Int32 and Double) implement IComparable, as do String, Char, and DateTime. Custom types should also provide their own implementation of IComparable to enable object instances to be ordered or sorted. I believe that might be the situation in your case. I hope this helps.
Try this:
...
Array.Sort(Of Integer)(someNumber) ' only if someNumber is not previously sorted
If Array.BinarySearch(Of Integer)(someNumber, MyEnum.Something) >= 0 Then
...
End If
...
This should work in all .NET frameworks > 2.0.
How do I go about to fixing this?
You are not using it correctly. BinarySearch is a Shared/static method and doesnt show in Intellisense when trying to use it as an instance method:
If you type it in anyway, you get a new compiler warning: Access of shared member ... through an instance ... will not be evaluated. MSDN doesnt have anything for NET 1.1, so I dont know if it changed since then (doubtful). Correct usage:
IndexOf6 = Array.BinarySearch(myIntAry, 6)
Which begs the question, as part of the conversion from NET 1.x to 4.5, why not convert this to List(Of Int32). A quick test shows that the IndexOf() method is 2-3 times faster:
IndexOf6 = intList.IndexOf(6)
The List<T> method is also more 'standalone' since unlike a System.Array, it need not be sorted in order to work.

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 to suppress compiler warning for specific function in VS2005 (VB.Net)

I have a class that inherits from a base class and implements the following...
Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
Now the base class it inherits from also implements this System.IComparable.CompareTo so I'm getting the following compiler warning:
Warning: 'System.IComparable.CompareTo' is already implemented by the base class. Re-implementation of function assumed.
I'm fine with that so my question is how can I suppress this warning for just this function (i.e. not all such warnings).
Clarifications:
Here is a link to the error on MSDN.
I've already tried both Shadows and Overrides and neither eliminates the warning.
The warning isn't on the method itself (unless Shadows or Overrides are omitted), but rather it's on "Implements System.IComparable.CompareTo" specifically.
I am not looking to suppress all warnings of this type (if they crop up), just this one.
Solution:
I was hoping to use the System.Diagnostics.CodeAnalysis.SuppressMessage attribute or something like C#'s #pragma but looks like there's no way to suppress the warning for a single line. There is a way to turn this message off for this project though, without turning all warnings off.
I manually edited the .vbproj file and included 42015 in the node for Debug and Release compilations. Not ideal but better than always seeing the warning in the IDE.
If someone has a better solution please add it and I'll gladly try it flag the answer.
Only use 'Implements' in the base class:
Signature in the base class:
Public Overridable Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
Signature in the inherited class:
Public Overrides Function CompareTo(ByVal obj As Object) As Integer
You can use the supress warnings just to suppress one warning. See here for more on how to.
You can also use the SuppressMessage Attribute.
If you don't have access to the base class and therefore can't make the method Overrideable, you can add <NoWarn>42015</NoWarn> to the project file.
Add the keyword Shadows to the function definition.
Public Shadows Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
Rather than suppressing the warning, shouldn't you be fixing it? Assuming that the base is Overridable,
Public Overrides Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
If not, then shadow it,
Public Shadows Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
(I think this is correct, I am a C# programmer. If not, please comment and I will update.)
On the properties of your project, go to the build tab and use the suppress warnings textbox.