microsoft / cppwinrt

C++/WinRT

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Map Windows::Foundation::Uri::Equals to operator==

JaiganeshKumaran opened this issue · comments

I noticed that operator== for Windows::Foundation::Uri wasn't overloaded and compares for identity which is unnatural and unintuitive as C++/WinRT projects WinRT classes as value types. This will be a breaking change but consider mapping operator== to Equals and don't repeat the same mistake done by Java and to some extent C#.

While WinRT doesn't provide a standardised interface for value equality, I noticed that a couple of OS WinRT classes have an IsEqual method (inconsistent with Uri::Equals). Could C++/WinRT map them to operator== based on the method name?

C++/WinRT already provides a custom operator== for IReference comparing values.

Reference types provide identity equality while value types provide value equality. We cannot easily change that without silently breaking existing code.

I understand but C++/WinRT projects these not as pointers or references but as value wrappers with smart pointer-like behaviour. While hard to change now, I would really suggest making this breaking change now (maybe even making it optional through a switch) because it is the right thing to do. Maybe users can be advised to get_abi(left) == get_abi(right) (or cast to IUnknown or IInspectable) going forward or provide a function like winrt::reference_equal to reliably compare identities.

I mean Uri is conceptually a reference type because that's how it is modeled in metadata: it derives from System.Object.

because it is the right thing to do

Whether it's the right thing to do is debatable, but it is a change in behavior that won't be caught at compile time and is therefore not something I can entertain.

I mean Uri is conceptually a reference type because that's how it is modeled in metadata: it derives from System.Object.

The main reason for this is WinRT structs can't contain any functionality. But the actual reference type is immutable and thus kind of looks like a value type with heap-allocated storage. And in .NET, System.Uri does have a value-based equality operator. What about ifdef-ing out overloads for operator== and make it opt-in?

Sorry, I don't see a compelling value in doing so at this stage. You can always provide your own "value equality" helper function.

This would also be a behavior change from C#.

Even in C#, Uri.operator= compares for value equality. Sure it's a reference type but that's really an implementation detail here in this case. Also in C++/WinRT, IReference already does value equality. I would say put an opt-in macro to enable this feature.

What WinRT really needs is an IEquatable interface, which could also work for C#.