Telegram.Bot
Telegram.Bot copied to clipboard
Use inheritance for the various types of a thing
Hi there. Currently, whenever an update comes in, for example, you need to check the value of the update.Type property and then use the corresponding property on the update object to access the relevant information:
public async Task HandleUpdateAsync(ITelegramBotClient bot, Update update, CancellationToken cancellationToken)
{
if (update.Type == UpdateType.ChannelPost)
{
var channelPost = update.ChannelPost;
// ...
}
}
But this is clearly kind of awkward, this seems like a PERFECT use case for inheritance, and the is operator, right?!
public async Task HandleUpdateAsync(ITelegramBotClient bot, Update update, CancellationToken cancellationToken)
{
if (update is ChannelPost channelPost)
{
// ...
}
}
I'm curious as to why the library wasn't designed this way, because it makes much, much more sense like this. This applies to things like Message.Type, etc. as well.
Thank you.
Since Update type lacks determinator field out of the box, it would require a custom serializer, which should decide which type of update we process.
This might lead to increased resource usage and an overall slowdown.
If you can provide us with a prototype (preferably with benchmark measurements) we would gladly implement this change.
I'm curious as to why the library wasn't designed this way, because it makes much, much more sense like this. This applies to things like Message.Type, etc. as well.
Mostly because official documentation and the API lack any way to know the type beforehand.
Although with Update type it's quite easy to determine the type, it's a completely different story for Message type where we can't really subdivide it into a hierarchy because we have no way to know to sure which fields can be present in each type of a message.
Regarding MessageType and UpdateType they are mostly for conveniece and from times where pattern matching was not as good as it is now. You can just use it instead of these properties. Like so:
if (update.ChannelPost is var channelPost)
{
// channelPost is not null here and you can process it
}
or
switch (update)
{
case { ChannelPost: var channelPost }:
{
HandleChannelPost(channelPost);
break;
}
case { Message: var message }:
{
HandleMessagePost(message);
break;
}
...
}
There is also a pretty hefty price to pay would we implement your proposal: pattern matching on types is much more costly in terms of performance than a single null check. I'd wait for discriminated unions proposal to be implemented first, I think Msft will take into account performance for pattern matching on DUs.
@tuscen var pattern is always true.
you need update.ChannelPost is {} channelPost