C
C#6mo ago
Keyde

✅ Avoid casting with inheritance chain

Hello, I'm facing a problem right now that I don't know how to handle without casting Imagine having a simple chat system with users (premium and classic) You want to display a dashboard score but only scoring users must be displayed in since there are no score for regular users. This is what I'm thinking of so far :
using System;
using System.Collections.Generic;

interface IUser
{
public string Id { get; }
}

interface IScoringUser : IUser
{
public int Score { get; }
}

class ClassicUser : IUser
{
public string Id { get; }
}

class PremiumUser : IScoringUser
{
public string Id { get; }

public int Score { get; }
}

class Chat
{
public List<IUser> Users { get; } = new();

public void JoinChat(IUser user)
{
Users.Add(user);
}
}

class ChatScoreDashboard
{
public void DisplayScore(Chat chat)
{
foreach (var user in chat.Users)
{
if (user is IScoringUser scoringUser)
{
Console.WriteLine(scoringUser.Score);
}
}
}
}
using System;
using System.Collections.Generic;

interface IUser
{
public string Id { get; }
}

interface IScoringUser : IUser
{
public int Score { get; }
}

class ClassicUser : IUser
{
public string Id { get; }
}

class PremiumUser : IScoringUser
{
public string Id { get; }

public int Score { get; }
}

class Chat
{
public List<IUser> Users { get; } = new();

public void JoinChat(IUser user)
{
Users.Add(user);
}
}

class ChatScoreDashboard
{
public void DisplayScore(Chat chat)
{
foreach (var user in chat.Users)
{
if (user is IScoringUser scoringUser)
{
Console.WriteLine(scoringUser.Score);
}
}
}
}
Can I handle this without casting? Maybe we could ask the user it's scoring, but I do not want to have any trace of scoring in regular users since they are not eligible for this feature. What about if we want to get all scoring users? Are there some edge cases where casting is just required?
6 Replies
jcotton42
jcotton426mo ago
I personally would not do this with separate types, it tends to be an antipattern have a Type or IsPremium prop on the user
Keyde
Keyde6mo ago
so you suggest having the Score prop for all users instead and check their types/flag instead?
jcotton42
jcotton426mo ago
yes
Keyde
Keyde6mo ago
I kind of agree, but I'm not comfortable about having a useless property for most of users. Basically, the property will be available in the contract for the user so it can be used elsewhere without a check on user type
alex
alex6mo ago
PremiumInfo class that holds all information for a premium user. add as property to User class/interface. null for normal user, instance for premium user. boom composition (class naming TBD)
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View