2

I know the question can be answered by saying foreach(var item in items){item.doSomething()}; but what i'm after is slightly different. Here is the interface.

ManagableClass .cs

public interface ManagableClass : System.IDisposable
{
    void Initialize();
}

and below is how I would like to see my code look like

MainManagerClass.cs

public class MainManagerClass: ManagableClass
{
    private List<ManagableClass> minions;

    public void Initialize()
    {
        TellMinionsTo(Initialize);
    }

    public void Dispose()
    {
        TellMinionsTo(Dispose);
    }

    private void TellMinionsTo(Action doSomething)
    {
        foreach (ManagableClass minion in minions)
        {
            minion.doSomething();
        }
    }
}

I know that this code that is here will not work, but it seems like this should be doable in C#. Anyone know if this can be done? If not it's not like it's the end of the world, I'll just do a foreach in each method.

Robert Snyder
  • 2,399
  • 4
  • 33
  • 65
  • is the list of minions going to be the same throughout each interface? i.e., should all derived classes be working w. the same list? – d.moncada May 17 '14 at 18:23
  • The list of minions will is of type `ManagableClass`, so they will have the 2 methods i'm after (Initialize, and Dispose) – Robert Snyder May 17 '14 at 18:39

2 Answers2

3

The problem with your code is that you pass a delegate to a method of a certain instance (yourself), while what you want is to invoke a certain method on all minions.

You can use lambda expressions, something like

public void Dispose()
{
   TellMinionsTo(minion=>minion.Dispose());
}    


private void TellMinionsTo(Action<ManagableClass> doSomething)
{
    foreach (ManagableClass minion in minions)
    {
         doSomething(minion);
    }
}

I don't like using List's method directly. Tomorrow you'll have to work via an interface and your IList may not have to be a List at all.

Ant P
  • 24,820
  • 5
  • 68
  • 105
Vadim
  • 2,847
  • 15
  • 18
  • I decided to switch to your answer, because although Gretro indirectly answered my question (I looked at intellisense with the ForEach method, and suprise it mataches your answer). But I like how the code reads as opposed to `minions.ForEach(i=>i.Dispose());` – Robert Snyder May 17 '14 at 18:58
2

What you are looking for is a Composite pattern. This pattern will allow you to have a class that will implement the correct method and differ it to a list of items. However, in your case, you need to modify your interface to implement the DoSomething() method. So, instead, this should look like this.

public interface ISomething
{
    void DoSomething();
}

public class SomethingManager : ISomething 
{
    private List<ISomething> _items = new List<ISomething>();

    public void DoSomething()
    {
        _items.ForEach(i => i.DoSomething());
    }
} 

Is that what you are looking for ?

gretro
  • 1,934
  • 15
  • 25
  • Although it isn't exactly what I was after, I didn't know List had an extension method of ForEach. Indirectly You answered my question. Somehow I thought I was implementing the Builder Design pattern (same website), thank you for correcting me on that. – Robert Snyder May 17 '14 at 18:38