if thing isa OtherThing then
var x as OtherThing = OtherThing( thing )
... more code that deals with x since its now an OtherThing
end if
OR
select case true
case thing isa otherType
.. cast to other type & work with the variable
case thing isa yetAnotherType
.. cast to yetAnotherType & work with the variable
end select
it sure would be nice to get rid of that boiler plate
not sure what other languages might have
Maybe some thing like
with thing as otherType
.. all the code that treats thing as an otherType
AND NO CAST REQUIRED HERE !!!!!!
end with
or
with thing as otherType
... thing is an otherType
NO CAST REQUIRED HERE !!!!!!
else with thing as yetAnotherType
... else thing is yetAnotherType
NO CAST REQUIRED HERE !!!!!!
else with
end with
“if thing isa OtherThing” sounds like thing is an Object (or in X terms, IIRC, Variant) boxing something and you have to figure out what it is? And the possibilities aren’t necessarily in the same inheritance tree or at least implementing the same interface?
I don’t recall X having generics and IIRC Buoy will, so … maybe there would, with proper design, be less need for this kind of thing to begin with.
But there are still situations where you can’t escape it. Still, something about having a variable name morph to a new type and back makes me a little bit uneasy in terms of code readability. Also it’s only buying you one less line of code per sub-block, if I’m understanding your scenario correctly.
I suppose the scenario might be something like examining every control on a window
In that case while they are all subclasses of UI Control or something like that you might want to treat each different based on type
for each ctrl as Control in Windows.Controls
select case true
case ctrl isa PushButton
dim pb as PushButton = pushbutton(ctrl)
... pb specific code ...
case ctrl isa CheckBox
dim cb as CheckBox = CheckBox(ctrl)
... cb specific code ...
... etc
in a long case like this ( assuming you handle may controls) while you save one line per block you could save a lot of lines overall
The other case I run into is Dictionaries in X
Or other similar code where what’s stored is some hierarchical arrangement of very generic data
I don’t expect it would save a lot of code though
Ah well this sounds like a use case for the GUI you’re designing. In line of business desktop apps I can’t remember the last time I had to iterate through controls for any purpose that would require me to access anything that’s not on the parent Control class API.
My thought in your shoes would likely be to ask myself how many users care about this and if it’s non-trivial to implement, I’d prioritize other features that will be of interest to the most users, particularly the target product audience and their core use cases.
OTOH I have my own pet ideas and wish lists, so I certainly understand how cool it is to get rid of little constant niggling pain points. They do add up!
So it turns out that this is not terribly hard to do. The compiler just needs to synthesize a shadowed variable inside the block for the original one. Using Norman’s original example, what happens under the hood is this:
with thing as otherType
dim thing as otherType = thing
... thing is an otherType
NO CAST REQUIRED HERE !!!!!!
else with thing as yetAnotherType
dim thing as yetAnotherType = thing
... else thing is yetAnotherType
NO CAST REQUIRED HERE !!!!!!
else
// thing is the original type here
end with
If you’re just looking for how other languages do things, C# does basically what I think you want like this:
private async void Header_OnDoubleTapped(object? Sender, TappedEventArgs E)
{
if (Sender is TextBlock textBlock)
{
// Now textBlock is a TextBlock
Console.WriteLine(textBlock.Text);
}
// Or if you want to get the tag property of a textblock into a variable
if (Sender is TextBlock { Tag: string tag })
{
// Now tag is a string, but there is no TextBlock variable defined
Console.Writeline(tag);
}
}
If you look at build 0.20.0, we introduced a new keyword “treat”
treat thing as otherType
// thing is othertype in this block
... thing is an otherType
NO CAST REQUIRED HERE !!!!!!
else treat thing as yetAnotherType
// thing is yetAnotherType in here
... else thing is yetAnotherType
NO CAST REQUIRED HERE !!!!!!
else
// thing is the original type here
end treat