TypeOf x Is SomeType sounds like an exact type check
- Dominant language
- No language data
- Stars
- 328
- Forks
- 71
- PR merge metrics
- No merged PRs in 30d
Description
Given the following declaration:
```vb
Dim s As Object = "abcd"
```
the following English statement would suggest an exact type check, on the concrete type of `s`:
> If the (concrete) type of `s` is `String` then ...
This is also what a straightforward reading of the `TypeOf` expression would suggest:
```vb
'If (the) TypeOf s Is String Then ...
If TypeOf s Is String Then ...
```
However, `TypeOf` doesn't work like that (nor should it):
```vb
If TypeOf s Is IEnumerable Then Console.WriteLine("True')
```
prints `True`, because `TypeOf x Is SomeType` is actually checking the following, in plain English:
> If the (concrete) type of `s` is type-compatible with `SomeType` then ...
where type-compatibility in this context means _equals `SomeType`, inherits from `SomeType` or implements `SomeType`_.
Obviously, programming languages are not natural languages, and we shouldn't expect to express the same meaning in the same way in both. However, I know that this disconnect between the syntax and what it is doing, is something that took me a while to wrap my head around, and I think we can find a more descriptive syntax for type-checking:
* either some variation of **`If s Is SomeType Then ...`** -- we aren't comparing two types, but rather asking if the object supports this type; there is no implication that `s` couldn't be of other types as well
* or **`If AnyTypeOf s Is SomeType Then ...`** -- expressly implying that `s` can have multiple types
I prefer the first choice, because it is more directly expresses what we are asking -- _if `s` is a/an `SomeType` then do something_. Under the hood, we are almost certainly extracting the concrete type from the object and checking its assignability with the named type (e.g. `Dim t = s.GetType(): If GetType(SomeType).IsAssignableFrom(t) Then...`) but I don't see the benefit in expressing this paradigm via the wording of the code. Also, the inverse -- `If NoTypeOf s Is IEnumerable Then...` is rather clumsy.
There is one issue with using `Is` / `IsNot` on its own: since `Is` also has meaning as reference equality check, how could the compiler differentiate between the two? I'm strongly tempted to suggest that the compiler could infer based on what is on the right-hand side of the `Is` -- a typename or an identifier. However, it is possible for a name to be both an identifier and a type name in the same scope; so I think this is infeasible as it would introduce ambiguity:
Dim s As String
Dim IEnumerable As IEnumerable = s
If s Is IEnumerable Then ... ' would this be a type check against the IEnumerable type, or a reference equality check against the IEnumerable variable?
Therefore I would suggest one of the following dedicated type check operators:
* **`If s IsOfType SomeType`** / **`If s IsNotOfType SomeType`**
* **`If s IsOf SomeType`** / **`If s IsNotOf SomeType`** -- this echoes generics, where `Of` is always followed by a type name
Even if this proposal is accepted, I don't think it possible to invalidate `TypeOf`. But I think the compiler/editor could rewrite `TypeOf` to the final form of this proposal; there are a few places where VB.NET already does a similar rewrite.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.