Closed aehancoc closed 1 month ago
May be related to https://github.com/dotnet/roslyn/issues/42816
IBitwiseOperators<byte,byte,byte>
are implemented explicitly for byte
, those methods are not public: https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Byte.cs,422
If you want to call into IBitwiseOperators<byte,byte,byte>.op_And
, you need to go through type parameter:
T And<T>(T l, T r) where T : IBitwiseOperators<T, T, T> => l & r;
byte a = 1, b = 2;
byte c = And(a, b);
Note that exposing those methods public on byte
is considered as a breaking change, as existing code expect it to be casted to int
.
I suppose that makes sense. The default behaviour is just a bit counter-intuitive imo. I'm assuming that it stems from the CIL's internal representation of integers as being at least 32 bits?
I'm not expecting anything to change, given the backwards compatibility requirements, so unless you want to reply then feel free to close this. (That said, I'm curious why the default integer promotion rules wouldn't be adequate if the methods were to be made public, but I'm sure there's plenty of edge cases I'm not considering.)
Consider:
Foo(b1 & b2)
void Foo(byte b) { ... }
void Foo(int i) { ... }
This can't change meaning.
Version Used:
Steps to Reproduce:
Observe this example.
Diagnostic Id:
CS0266: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Expected Behavior:
Because
System.Byte
implementsSystem.Numerics.IBitwiseOperators<byte,byte,byte>
as seen here, this should compile without issue. This occurs even if using a constant, likebyte b = a & (byte)2;
.Interestingly, this works fine in VB.NET (example) and in F# (example).
Actual Behavior:
Compilation error is raised, because for whatever reason the compiler elects to cast some part of this to an
int
. The easiest workaround (and what the VB.NET/F# examples decompile to) isbyte b = (byte)(a & a);
, but this feels clunky.