Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3300712
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T20:41:11+00:00 2026-05-17T20:41:11+00:00

This is quite a common problem I run into. Let’s hear your solutions. I’m

  • 0

This is quite a common problem I run into. Let’s hear your solutions. I’m going to use an Employee-managing application as an example:-

We’ve got some entity classes, some of which implement a particular interface.

public interface IEmployee { ... }
public interface IRecievesBonus { int Amount { get; } }
public class Manager : IEmployee, IRecievesBonus { ... }
public class Grunt : IEmployee /* This company sucks! */ { ... }

We’ve got a collection of Employees that we can iterate over. We need to grab all the objects that implement IRecievesBonus and pay the bonus.

The naive implementation goes something along the lines of:-

foreach(Employee employee in employees)
{
  IRecievesBonus bonusReciever = employee as IRecievesBonus;
  if(bonusReciever != null)
  {
    PayBonus(bonusReciever);
  }
}

or alternately in C#:-

foreach(IRecievesBonus bonusReciever in employees.OfType<IRecievesBonus>())
{
  PayBonus(bonusReciever);
}
  • We cannot modify the IEmployee interface to include details of the child type as we don’t want to pollute the super-type with details that only the sub-type cares about.
  • We do not have an existing collection of only the subtype.
  • We cannot use the Visitor pattern because the element types are not stable. Also, we might have a type which implements both IRecievesBonus and IDrinksTea. Its Accept method would contain an ambiguous call to visitor.Visit(this).

Often we’re forced down this route because we can’t modify the super-type, nor the collection e.g. in .NET we may need to find all the Buttons on this Form via the child Controls collection. We may need to do something to the child types that depends on some aspect of the child type (e.g. the bonus amount in the example above).

Strikes me as odd that there isn’t an “accepted” way to do this, given how often it comes up.

1) Is the type conversion worth avoiding?

2) Are there any alternatives I haven’t thought of?

EDIT

Péter Török suggests composing Employee and pushing the type conversion further down the object tree:-

public interface IEmployee
{
  public IList<IEmployeeProperty> Properties { get; }
}

public interface IEmployeeProperty { ... }

public class DrinksTeaProperty : IEmployeeProperty
{
  int Sugars { get; set; }
  bool Milk { get; set; }
}

foreach (IEmployee employee in employees)
{
  foreach (IEmployeeProperty property in employee.Propeties)
  {
    // Handle duplicate properties if you need to.
    // Since this is just an example,  we'll just
    // let the greedy ones have two cups of tea.
    DrinksTeaProperty tea = property as DrinksTeaProperty;
    if (tea != null)
    {
      MakeTea(tea.Sugers, tea.Milk);
    }
  }
}

In this example it’s definitely worth pushing these traits out of the Employee type – particularly because some managers might drink tea and some might not – but we still have the same underlying problem of the type conversion.

Is it the case that it’s “ok” so long as we do it at the right level? Or are we just moving the problem around?

The holy grail would be a variant on the Visitor pattern where:-

  • You can add element members without modifying all the visitors
    • Visitors should only visit types they’re interested in visiting
  • The visitor can visit the member based on an interface type
    • Elements might implement multiple interfaces which are visited by different visitors
  • Doesn’t involve casting or reflection

but I appreciate that’s probably unrealistic.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T20:41:11+00:00Added an answer on May 17, 2026 at 8:41 pm

    I would definitely try to resolve this with composition instead of inheritance, by associating the needed properties/traits to Employee, instead of subclassing it.

    I can give an example partly in Java, I think it’s close enough to your language (C#) to be useful.

    public enum EmployeeProperty {
      RECEIVES_BONUS,
      DRINKS_TEA,
      ...
    }
    
    public class Employee {
      Set<EmployeeProperty> properties;
      // methods to add/remove/query properties
      ... 
    }
    

    And the modified loop would look like this:

    foreach(Employee employee in employees) {
      if (employee.getProperties().contains(EmployeeProperty.RECEIVES_BONUS)) {
        PayBonus(employee);
      }
    }
    

    This solution is much more flexible than subclassing:

    • it can trivially handle any combination of employee properties, while with subclassing you would experience a combinatorial explosion of subclasses as the number of properties grow,
    • it trivially allows you to change Employee properties runtime, while with subclassing this would require changing the concrete class of your object!

    In Java, enums can have properties or (even virtual) methods themselves – I don’t know whether this is possible in C#, but in the worst case, if you need more complex properties, you can implement them with a class hierarchy. (Even in this case, you are not back to square one, since you have an extra level of indirection which gives you the flexibility described above.)

    Update

    You are right that in the most general case (discussed in the last sentence above) the type conversion problem is not resolved, just pushed one level down on the object graph.

    In general, I don’t know a really satisfying solution to this problem. The typical way to handle it is using polymorphism: pull up the common interface and manipulate the objects via that, thus eliminating the need for downcasts. However, in cases when the objects in question do not have a common interface, what to do? It may help to realize that in these cases the design does not reflect reality well: practically, we created a marker interface solely to enable us to put a bunch of distinct objects into a common collection, but there is no semantical relationship between the objects.

    So I believe in these cases the awkwardness of downcasts is a signal that there may be a deeper problem with our design.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.