Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Select Type #7545

Closed
AdamSpeight2008 opened this issue Dec 16, 2015 · 3 comments
Closed

[Proposal] Select Type #7545

AdamSpeight2008 opened this issue Dec 16, 2015 · 3 comments

Comments

@AdamSpeight2008
Copy link
Contributor

The premise of a Select Type is to act like a Select Case but allow the selection to use types.

Grammar (v1)

SelectType          ::= SelectType_Header SelectType_Body SelectType_Footer
SelectType_Header   ::= "Select" ws+ "Type" ws+ identifer ws* eol
SelectType_Footer   ::= "End" ws+ "Select" ws* eol
SelectType_Body     ::= SelectType_Expr* SelectType_Else?
SelectType_ELse     ::= ws* "Case" ws+ "Else" eol SelectType_ExprBody
SelectType_Expr     ::= ws* "Case" ws+ SelectType_ExprHead SelectType_ExprInto? (eol |( ws+ ":" ws+)) SelectType_ExprBody
SelectType_ExprHead ::= type_identifier (ws* "," ws* type_identifier)*
SelectType_ExprInto ::= "Into" ws+ identifier ws+
SelectType_ExprBody ::= expression eol
Case Type obj
  Case T0 
     ...
  Case T1 Into x
     ' x = DirectCase(obj, T1)
  Case Else
  ...
End Select

A current work-around

If TypeOf value Is Boolean Then
  Dim boolValue = DirectCast(value, Boolean)
  If boolValue Then Return SyntaxFactory.TrueLiteralExpression(SyntaxFactory.Token(SyntaxKind.TrueKeyword))
  Return SyntaxFactory.FalseLiteralExpression(SyntaxFactory.Token(SyntaxKind.FalseKeyword))
ElseIf TypeOf value Is String Then
  Return GenerateStringLiteralExpression(type, DirectCast(value, String))
ElseIf TypeOf value Is Char Then
  Return GenerateCharLiteralExpression(DirectCast(value, Char))
ElseIf TypeOf value Is SByte Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_SByte, value, canUseFieldReference, LiteralSpecialValues.SByteSpecialValues)
ElseIf TypeOf value Is Short Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_Int16, value, canUseFieldReference, LiteralSpecialValues.Int16SpecialValues)
ElseIf TypeOf value Is Integer Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_Int32, value, canUseFieldReference, LiteralSpecialValues.Int32SpecialValues)
ElseIf TypeOf value Is Long Then
  Return GenerateLongLiteralExpression(type, DirectCast(value, Long), canUseFieldReference)
ElseIf TypeOf value Is Byte Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_Byte, value, canUseFieldReference, LiteralSpecialValues.ByteSpecialValues)
ElseIf TypeOf value Is UShort Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt16, value, canUseFieldReference, LiteralSpecialValues.UInt16SpecialValues)
ElseIf TypeOf value Is UInteger Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt32, value, canUseFieldReference, LiteralSpecialValues.UInt32SpecialValues)
ElseIf TypeOf value Is ULong Then
  Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt64, value, canUseFieldReference, LiteralSpecialValues.UInt64SpecialValues)
ElseIf TypeOf value Is Single Then
  Return GenerateSingleLiteralExpression(type, DirectCast(value, Single), canUseFieldReference)
ElseIf TypeOf value Is Double Then
  Return GenerateDoubleLiteralExpression(type, DirectCast(value, Double), canUseFieldReference)
ElseIf TypeOf value Is Decimal Then
  Return GenerateDecimalLiteralExpression(type, DirectCast(value, Decimal), canUseFieldReference)
ElseIf TypeOf value Is DateTime Then
  Return GenerateDateLiteralExpression(DirectCast(value, DateTime))
Else
  Return GenerateNothingLiteral()
End If

Using Select Type

Select Type value
  Case Boolean Into boolValue
    If boolVaue Then
      Return SyntaxFactory.TrueLiteralExpression(SyntaxFactory.Token(SyntaxKind.TrueKeyword))
    Else
      Return SyntaxFactory.FalseLiteralExpression(SyntaxFactory.Token(SyntaxKind.FalseKeyword))
    End If
  Case String   Into s  : Return GenerateStringLiteralExpression(type, s))
  Case Char     Into c  : Return GenerateCharLiteralExpression(c)
  Case SByte    Into sb : Return GenerateIntegralLiteralExpression(type, SpecialType.System_SByte, value, canUseFieldReference, LiteralSpecialValues.SByteSpecialValues)
  Case Short            : Return GenerateIntegralLiteralExpression(type, SpecialType.System_Int16, value, canUseFieldReference, LiteralSpecialValues.Int16SpecialValues)
  Case Integer          : Return GenerateIntegralLiteralExpression(type, SpecialType.System_Int32, value, canUseFieldReference, LiteralSpecialValues.Int32SpecialValues)
  Case Long     Into l  : Return GenerateLongLiteralExpression(type, l, canUseFieldReference)
  Case Byte     Into b  : Return GenerateIntegralLiteralExpression(type, SpecialType.System_Byte, value, canUseFieldReference, LiteralSpecialValues.ByteSpecialValues)
  Case UShort           : Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt16, value, canUseFieldReference, LiteralSpecialValues.UInt16SpecialValues)
  Case UInteger         : Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt32, value, canUseFieldReference, LiteralSpecialValues.UInt32SpecialValues)
  Case ULong            : Return GenerateIntegralLiteralExpression(type, SpecialType.System_UInt64, value, canUseFieldReference, LiteralSpecialValues.UInt64SpecialValues)
  Case Single   Into s  : Return GenerateSingleLiteralExpression(type, s, canUseFieldReference)
  Case Double   Into d  : Return GenerateDoubleLiteralExpression(type, d, canUseFieldReference)
  Case Decimal  Into d  : Return GenerateDecimalLiteralExpression(type, d, canUseFieldReference)
  Case DateTime Into dt : Return GenerateDateLiteralExpression(dt)
  Case Else
    Return GenerateNothingLiteral()
End Select
@HaloFour
Copy link

Is this in lieu of actual pattern matching syntax for VB.NET?

Given VB.NET's declaration syntax I would expect a syntax for this functionality to more look like this:

Select Case obj
    Case s As String
        WriteLine($"The value is ""{s}"".")
    Case p As Person
        WriteLine($"The value is a person with the name ""{p.Name}"".")
End Select

Have there been any syntax proposals for pattern matching in VB.NET at all?

@gafter
Copy link
Member

gafter commented Dec 16, 2015

Our pattern-matching work is intended to extend to both C# and VB. We believe that pattern-matching is a much better fit for the use cases to which this feature would apply.

@alrz
Copy link
Contributor

alrz commented Dec 17, 2015

Still, I hope identifier could be optional for type checks, like switch .. case Foo: .. and constant-pattern would be just a constant-expression just like F#. It'll be specifically useful with #6235 and #6789.

@gafter gafter closed this as completed Dec 17, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants