Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract base class or Interface? Neither seem right

Given the following code:

using System.Collections.Generic;
static class Program {
    static void Main() {
        bar Bar = new bar();
        baz Baz = new baz();
        System.Console.WriteLine(
            "We have {0} bars, rejoice!", bar.Cache.Count);
    }
}

public abstract class foo {
    public static List<foo> Cache = new List<foo>(); 
}

public class bar : foo {
    public bar() { Cache.Add(this); }
}
public class baz : foo {
    public baz() { Cache.Add(this); }
}

You get the (somewhat expected) output "We have 2 bars, rejoice!".

This is fabulous, we now have twice as many places to have our beer (apparently), but what I really want is for each class to have it's own cache. The reason I don't want to just implement this cache in the subclass is because I also have some methods in my abstract class that needs to be able to operate on the cache (namely, to iterate over all of them). Is there a way to do this? I've looked at using an interface for foo, but the interface doesn't allow static members to be defined as part of the interface.

like image 992
Matthew Scharley Avatar asked Dec 18 '22 08:12

Matthew Scharley


2 Answers

Each derived class of foo should define how/where to get a cache, so each can (potentially) have its own cache. Methods in foo can refer to GetCache() without the implementation being known.

public abstract class foo
{
    public abstract ICache GetCache();

    public void DoSomethingToCache()
    {
        ICache cache = this.GetCache();
        cache.DoSomething();
    }
}

public class bar : foo
{
    public static ICache BarCache = new FooCache();

    public override ICache GetCache()
    {
        return bar.BarCache;
    }
}

public class FooCache : ICache { }
like image 106
Rex M Avatar answered Dec 29 '22 15:12

Rex M


Use a generic base class parameterized with the subclass:

using System.Collections;
using System.Collections.Generic;

static class Program
{
    static void Main()
    {
        bar Bar = new bar();
        baz Baz = new baz();
        System.Console.WriteLine(
                "We have {0} bars, rejoice!", Bar.GetCache().Count);
    }
}

public abstract class foo<T>
{
    private static List<foo<T> > Cache = new List<foo<T> >();

    public IList GetCache()
    {
        return Cache;
    }
}

public class bar : foo<bar>
{
    public bar() { GetCache().Add(this); }
}
public class baz : foo<baz>
{
    public baz() { GetCache().Add(this); }
}
like image 41
Carlos A. Ibarra Avatar answered Dec 29 '22 15:12

Carlos A. Ibarra