Open AdamSpeight2008 opened 5 years ago
Checked Expressions
If you need to implement unchecked conversions between Byte
and SByte
without changing the project settings, you can use the following code. It's as fast as the unchecked CByte
operator on .NET Core 2.2 x64.
Module SByteAndByteBitConverter
<StructLayout(LayoutKind.Explicit)>
Private Structure SByteByteUnion
<FieldOffset(0)>
Dim SByteValue As SByte
<FieldOffset(0)>
Dim ByteValue As Byte
End Structure
<Extension>
Public Function AsByte(SByteValue As SByte) As Byte
Return (New SByteByteUnion With {.SByteValue = SByteValue}).ByteValue
End Function
<Extension>
Public Function AsSByte(ByteValue As Byte) As SByte
Return (New SByteByteUnion With {.ByteValue = ByteValue}).SByteValue
End Function
End Module
Usage
Dim sb As SByte = -100
Dim ub As Byte = sb.AsByte
This has already been vaguely proposed a long time ago, see #84 and I'd like to highlight the example there that has bothered me a lot of dirty workarounds already: Currently you are not able to implement hashing algorithms, see for example What is the best algorithm for an overridden GetHashCode
?
Just updating everyone to say there is a prototype implementation at #41104 for this feature.
I was working on a NuGet Library but I love if it were built into the compiler. I am playing with BigInteger which would allow conversion from Byte/SByte all the way to ULong/Long but none of it solves the overflow by the compiler itself.
Dim X as byte = CByte(Long.MaxValue + 1)
' Even Unchecked
Dim Y as Byte =CBtype(UnChecked(Long.MaxValue + 1))
@paul1956
Module M
Sub Main()
Dim i1 As ULong = ULong.MaxValue
Dim i2 as ULong= Unchecked( i1 + 1UL)
System.Console.WriteLine(i2)
End Sub
End Module
Will output 0
to the console. Changing the expression from 1UL
to 1
results in an upcast being performed converting both side to Decimal
then a downcast. Unchecked
will not change that.
@paul1956 My implementation is more of a proof of concept,
BoundExpression
already has support for checked / unchecked expressions. @AdamSpeight2008 Based on comment from PR are you going to continue to follow up with this?
@paul1956 I'll still work on it, even if it is just for my edification.
Why not just follow instruction in PR #41104 and get support assuming your implementation provides the needed functionality you would get lots of user support.
Meanwhile, I've created a nuget package for unchecked integer operations in VB.NET, see nuget package VBMath.Unchecked or Github repository System.Runtime.Extensions.Unchecked.
Using System.Numerics
' this will not throw
Dim value = UncheckedInteger.Add(Integer.MaxValue, 1)
Related: #180
Checked Expressions
C# has the the concept of check and unchecked expressions, I think we should also bring into VB.net as well. Implicitly assumed to be
Checked expression
unless explicitly statedUnchecked
, as to retain backwards compatibility, We can do this by introducing a new keywordChecked
, that acts like a prefix operator on expressions. egThis is useful when you explicitly want to cast to and from signed to unsigned types, without thrown an exception.
Checked For Loop
A
For-Loop
is implicitly unchecked (ie it throws exceptions) about being out of range. By prefixing the control variable withChecked
egFor Checked index As Sbyte = SByte.MinValue To SByte,MaxValue Step 2
. The control variable is checked to remain within the range stated, this has the side-effect of control variable after the final iteration of the loop, not having a value beyond the end value (SByte.MaxValue
in the example). This allows the full range of the value types. eg.MinValue To .MaxValue
This can be achieved by altering the lowering of the for loop, in the checked case.
Rough Lowering for Checked For Loop