1

I am working on some C# code which uses the .NET class Microsoft.VisualBasic.CompilerServices.LikeOperator. (Some additional context: I am porting this code to target .NET Standard 2.0, which does not support that class. It is missing from the .NET Standard 2.0 flavor of the Microsoft.VisualBasic nuget package. So I would like to replace the usage of LikeOperator, but unfortunately there is other code and maybe even end users which depend on the pattern language.)

While playing with LikeOperator.LikeString to make sure that I understand exactly what it does, I got an unexpected result. I used the pattern "foo*?bar" to express that I want to match any string which starts with "foo", ends with "bar", and has one or more characters in between.

However, the following call unexpectedly returns true:

LikeOperator.LikeString("foobar", "foo*?bar", CompareMethod.Text)

As far as I understand, the ? wildcard should force at least one character to be present between foo and bar, so I don't understand this result. Are these adjacent *? wildcards a special case?

edit: the like operator does seem to work as expected when tested in the VB.NET implementation of mono 6.12.0. So there seems to be a difference between the .NET Framework and mono here. Could this actually be a bug in Microsoft's implementation?

Wim Coenen
  • 66,094
  • 13
  • 157
  • 251
  • I would stay away from using it. It works if you use "foo?bar", though, which is logically the same. – Palle Due Oct 05 '22 at 11:41
  • @PalleDue the LikeOperator class is already used. I am working on replacing the usage of this class, which is why I must understand how it works. – Wim Coenen Oct 05 '22 at 11:42
  • I understand, but do you need to implement it's bugs also? I've reproduced your example and I don't think it was meant to behave that way. – Palle Due Oct 05 '22 at 11:48
  • If it is a bug then I would indeed not care about reproducing that behavior. I just want to make sure first that it is actually a bug, and not a misunderstanding on my part. – Wim Coenen Oct 05 '22 at 11:52
  • @PalleDue No, `"foo?bar"` is logically *not* the same: it doesn’t match `"fooxyzbar"`, whereas OP’s pattern does. – Konrad Rudolph Oct 05 '22 at 11:58
  • @KonradRudolph: You're right. – Palle Due Oct 05 '22 at 12:05
  • @WimCoenen why is `Like` used at all? And why should its use be migrated to .NET Standard 2.0 in 2022? `Like` is missing because it was actively removed and isn't coming back. It had a use to allow migrating from VB6 to VB.NET but offered no benefit compared to regular expressions. Regular expressions have gotten a *lot* of performance improvements over the years, while `Like` was simply abandoned – Panagiotis Kanavos Oct 05 '22 at 13:27
  • @WimCoenen Mono isn't a Microsoft project anyway and can't be used as a reference. The cross-platform runtime, .NET Core, doesn't have `Like` either. Mono should be a concern only if you target Xamarin – Panagiotis Kanavos Oct 05 '22 at 13:28
  • @PanagiotisKanavos Like is used because this C# code has a history all the way back to the days of .NET Framework 1.1, and was written in an environment where many of the devs where familiar with VB6 and vbscript. It is being ported to .NET Standard 2.0 now to make it compatible with both .NET Framework and newer .NET implementations like .NET 6. A large amount of other code builds on top of it, so getting rid of it is like pulling a block from a Jenga stack. – Wim Coenen Oct 05 '22 at 13:40
  • @WimCoenen I understood that, as I've worked with VB6 20 years ago and companies that tried to ignore problems instead of fixing them. I can even guess you need to support MacOS, hence the requirement for Mono. The stack is already falling though. There were 20 years to delete this technical debt rather than compound it. At this point you *have* to reproduce the bugs or actually fix the problem. BTW Mono was (in)famous for reproducing even buggy results to ensure maximum compatibility. That was before Microsoft bought Xamarin – Panagiotis Kanavos Oct 05 '22 at 13:54
  • @WimCoenen in any case, if you want to replicate `Like`'s behavior you'll have to use .NET Framework, not Mono. If what you see is a bug that existed in the past and was fixed you'll have to investigate and decide whether your codebase depends on the bug or not. And whether you want to replicate the bug – Panagiotis Kanavos Oct 05 '22 at 13:56
  • @WimCoenen unfortunately, in VB.NET for .NET Framework 4.8, `Console.WriteLine("foobar" Like "foo*?bar")` prints `True`. In Excel VBA `"foobar" Like "foo*?bar"` evaluates to False. It's quite possible this bug was introduced sometime in the last 20 years but never fixed for fear of breaking code. Or it was never noticed - even VB6 devs used regular expressions. You'll have to decide which version to choose, and whether your own code depends on the bug. VB6 was *notorious* for its inconsistency as there never was a formal language specification. Features were directly added to the compiler. – Panagiotis Kanavos Oct 05 '22 at 14:03
  • @PanagiotisKanavos thanks, the inconsistency between .NET Framework and VBA is an interesting additional data point. We will probably do something like the mono codebase, where they translate these Like patterns to regex. It's unlikely we rely on the buggy behavior, but we'll deal with it if it turns out that we do. – Wim Coenen Oct 05 '22 at 14:16
  • Since the late 1990s VBScript and VB6 developers used the [FileSystemObject](https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/filesystemobject-object) and [RegExp](https://www.tutorialspoint.com/vbscript/vbscript_reg_expressions.htm) objects for file access and pattern matching instead of `Open` and `Like`. It's way past time such code was removed. I don't remember ever using `Like` since 2000 - even back then I added the Scripting Runtime reference to projects and used FileSystemObject or RegExp directly – Panagiotis Kanavos Oct 05 '22 at 14:16
  • `We will probably do something like the mono codebase` are you sure this will cost any less than abandoning `Like` ? In any case, VB's `Like` is similar to SQL's LIKE. You could [adapt these answers](https://stackoverflow.com/questions/5417070/c-sharp-version-of-sql-like) to work with VB6 syntax. The accepted answer shows how to convert a `LIKE` pattern to a Regular Expression before executing it. You get the perf improvements, a maintainable "parser" and a starting point towards eliminating `Like` – Panagiotis Kanavos Oct 05 '22 at 14:25

0 Answers0