3

Using VB.NET, I'm trying to clean up a code base following ReSharper's guidelines. I currently have the following code:

'oSearchInput is defined outside this question
Dim oSearchRoutines As New SearchClient
Dim oSearchResults As List(Of SearchResult)

oSearchRoutines = 'WcfCallThatReturnsSearchClient

oSearchResults = oSearchRoutines.getSearchResults(oSearchInput).ToList

Now this works completely fine, but ReSharper warns that As New SearchClient has 'Value assigned is not used in any execution path'. So I removed that part to get this code:

'oSearchInput is defined outside this question
Dim oSearchRoutines
Dim oSearchResults As List(Of SearchResult)

oSearchRoutines = 'WcfCallThatReturnsSearchClient

oSearchResults = oSearchRoutines.getSearchResults(oSearchInput).ToList

If I'm understanding this correctly, everything should work exactly the same. However, an error is thrown when calling ToList:

Public member 'ToList' on type 'SearchResult()' not found.

I'm not exactly sure why there's any difference between the two snippets I have here.

MatSnow
  • 7,357
  • 3
  • 19
  • 31
Mike
  • 517
  • 2
  • 5
  • 21
  • 2
    `As New SearchClient` does more than declare the type, it creates the object. If later you assign the object from the Wcf method, the first one was not used and was created for no reason. The second declaration, `Dim oSearchRoutines` will not compile under Option Strict and is just System.Object. You can declare a type without creating it: `Dim oSearchRoutines As SearchClient` – Ňɏssa Pøngjǣrdenlarp Dec 05 '17 at 15:49
  • I'm not completely sure, but I think the error message is arising from an intersection of late binding and extension methods. `ToList` is an extension method provided by Linq, so when you declare the type of `oSearchRoutines` explicitly, the compiler knows how to find `ToList`, but when it is of type `Object`, the runtime resolution doesn't find the extension method. – Craig Dec 05 '17 at 16:28

1 Answers1

4

Because you're not assinging the type SearchClient in your second example, oSearchRoutines will automatically be of type Object.

An expression of type Object is mainly not allowed to use Extension methods, like for example the ToList-method. For further information see here

The following example illustrates this behaviour:

Dim x As Object
Dim y As String = "ABC"
x = y

Dim a As List(Of Char) = y.ToList() 'This will work
Dim b As List(Of Char) = x.ToList() 'This will throw a System.MissingMemberException

The message Value assigned is not used in any execution path, appears because you're declaring oSearchRoutines with New in your first example. This is unnecessary because you're assinging a new value to it on the line...

oSearchRoutines = 'WcfCallThatReturnsSearchClient

...before using it anywhere.

Thus you can just declare it without the keyword New

Dim oSearchRoutines As SearchClient

Related question: VB.NET: impossible to use Extension method on System.Object instance

MatSnow
  • 7,357
  • 3
  • 19
  • 31
  • I don't think your diagnosis is exactly correct. VB can and does late-bind on `Object` variables, and indeed that seems to be happening here. The error is *not* that there is no `getSearchResults` method, rather that there is no `ToList` on the return type from `getSearchResults`. – Craig Dec 05 '17 at 16:26
  • 1
    @Craig Thanks for your comment. I've edited my answer. The problem is not that the compiler wouldn't find the extension method, but isn't allowed to use it due to security reasons. – MatSnow Dec 06 '17 at 08:18