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

Select Case on identity (reference equality) #119

Open
AnthonyDGreen opened this issue Jun 28, 2017 · 2 comments
Open

Select Case on identity (reference equality) #119

AnthonyDGreen opened this issue Jun 28, 2017 · 2 comments

Comments

@AnthonyDGreen
Copy link
Contributor

Today you can do a Select Case on value equality. There have been requests to extend this to support reference equality too:

Select Case obj
    Case Is objA

    Case Is objB

    Case IsNot Nothing

    Case Is Nothing

End Select

This seems like a reasonable extension of the language and customers have requested it before.

@AnthonyDGreen AnthonyDGreen added this to the VB15.x candidate milestone Jun 28, 2017
@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Jul 5, 2017

Grammar

CaseRelationalClause  ::= "Case" ws+ Relational Introduction? Guard?
Relational            ::= TypeRelational
TypeRelational        ::= IsOperator TypeRelationalTarget
TypeRelationalTarget  ::= TypeIdentifer | Identifer
IsOperator            ::= "Is" | "IsNot"
Introduction          ::= ws+ "InTo" identifier
Guard                 ::= ws+ "When" ws+ expr<Bool>

So given the following simplified extract from the roslyn source code.

Public Function FormatPrimitive(obj As Object, options As ObjectDisplayOptions) As String
  If obj Is Nothing Then Return NullLiteral

  Dim type = obj.GetType()
  If type.GetTypeInfo().IsEnum Then type = [Enum].GetUnderlyingType(type)

  If type Is GetType(Integer)  Then Return FormatLiteral(DirectCast(obj, Integer), options)
  If type Is GetType(String)   Then Return FormatLiteral(DirectCast(obj, String), options)
  If type Is GetType(Boolean)  Then Return FormatLiteral(DirectCast(obj, Boolean))
  If type Is GetType(Char)     Then Return FormatLiteral(DirectCast(obj, Char), options)
  If type Is GetType(Byte)     Then Return FormatLiteral(DirectCast(obj, Byte), options)
  If type Is GetType(Short)    Then Return FormatLiteral(DirectCast(obj, Short), options)
  If type Is GetType(Long)     Then Return FormatLiteral(DirectCast(obj, Long), options)
  If type Is GetType(Double)   Then Return FormatLiteral(DirectCast(obj, Double), options)
  If type Is GetType(ULong)    Then Return FormatLiteral(DirectCast(obj, ULong), options)
  If type Is GetType(UInteger) Then Return FormatLiteral(DirectCast(obj, UInteger), options)
  If type Is GetType(UShort)   Then Return FormatLiteral(DirectCast(obj, UShort), options)
  If type Is GetType(SByte)    Then Return FormatLiteral(DirectCast(obj, SByte), options)
  If type Is GetType(Single)   Then Return FormatLiteral(DirectCast(obj, Single), options)
  If type Is GetType(Decimal)  Then Return FormatLiteral(DirectCast(obj, Decimal), options)
  If type Is GetType(Date)     Then Return FormatLiteral(DirectCast(obj, Date))
  Return Nothing
End Function

rewritten using Relational Case Clause, with variable declaration introduction.

Public Function FormatPrimitive(obj As Object, options As ObjectDisplayOptions) As String
  If obj Is Nothing Then Return NullLiteral

  Dim type = obj.GetType()
  If type.GetTypeInfo().IsEnum Then type = [Enum].GetUnderlyingType(type)
  Select Case type
    Case Is Integer  InTo res  : Return FormatLiteral(res, options)
    Case Is String   InTo res  : Return FormatLiteral(res, options)
    Case Is Boolean  InTo res  : Return FormatLiteral(res)
    Case Is Char     InTo res  : Return FormatLiteral(res, options)
    Case Is Byte     InTo res  : Return FormatLiteral(res, options)
    Case Is Short    InTo res  : Return FormatLiteral(res, options)
    Case Is Long     InTo res  : Return FormatLiteral(res, options)
    Case Is Double   InTo res  : Return FormatLiteral(res, options)
    Case Is ULong    InTo res  : Return FormatLiteral(res, options)
    Case Is UInteger InTo res  : Return FormatLiteral(res options)
    Case Is UShort   InTo res  : Return FormatLiteral(res, options)
    Case Is SByte    InTo res  : Return FormatLiteral(res, options)
    Case Is Single   InTo res  : Return FormatLiteral(res, options)
    Case Is Decimal  InTo res  : Return FormatLiteral(res, options)
    Case Is Date     InTo res  : Return FormatLiteral(res)
    Case Else
      Return Nothing
  End Select
End Function

become rather clean looking code.

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Oct 21, 2017

Using Select Type

Public Function FormatPrimitive(obj As Object, options As ObjectDisplayOptions) As String
  If obj Is Nothing Then Return NullLiteral

  Dim type = obj.GetType()
  If type.GetTypeInfo().IsEnum Then type = [Enum].GetUnderlyingType(type)
  Select Type type
    Case Integer  Out res : Return FormatLiteral(res, options)
    Case String   Out res : Return FormatLiteral(res, options)
    Case Boolean  Out res : Return FormatLiteral(res)
    Case Char     Out res : Return FormatLiteral(res, options)
    Case Byte     Out res : Return FormatLiteral(res, options)
    Case Short    Out res : Return FormatLiteral(res, options)
    Case Long     Out res : Return FormatLiteral(res, options)
    Case Double   Out res : Return FormatLiteral(res, options)
    Case ULong    Out res : Return FormatLiteral(res, options)
    Case UInteger Out res : Return FormatLiteral(res options)
    Case UShort   Out res : Return FormatLiteral(res, options)
    Case SByte    Out res : Return FormatLiteral(res, options)
    Case Single   Out res : Return FormatLiteral(res, options)
    Case Decimal  Out res : Return FormatLiteral(res, options)
    Case Date     Out res : Return FormatLiteral(res)
    Case Else             : Return Nothing
  End Select
End Function

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

2 participants