Abstract base class or interface? Doesn't 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) conclusion "We have 2 bars, rejoice!".

It's awesome, now we have twice as many places for beer (apparently), but I really want each class to have its own cache. The reason I don't want to just implement this cache in a subclass is because I also have some methods in my abstract class that should be able to work in the cache (namely, iterating over all of them). Is there any way to do this? I have considered using the interface for foo , but the interface does not allow static members to be defined as part of the interface.

+4
source share
5 answers

Each derived class foo must determine how / where to get the cache, so everyone can (potentially) have their own cache. Methods in foo can reference GetCache () without a known implementation.

 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 { } 
+8
source

Use a common base class parameterized by a 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); } } 
+4
source
 public abstract class foo { public abstract List<foo> Cache { get; } protected static Dictionary<Type, List<foo>> InnerCache = new Dictionary<Type, List<foo>>(); } public class bar : foo { public override List<foo> Cache { get { return foo.InnerCache[typeof(bar)]; } } public bar() { Cache.Add(this); } } public class baz : foo { public override List<foo> Cache { get { return foo.InnerCache[typeof(baz)]; } } public baz() { Cache.Add(this); } } 
+1
source

Here is your answer:

 using System; using System.Collections.Generic; static class Program { static void Main() { var bar = new Bar(); var baz = new Baz(); System.Console.WriteLine( "We have {0} bars, rejoice!", Bar.Cache.Count); bar.PrintList(); baz.PrintList(); } } public abstract class Foo<T> { public static List<T> Cache = new List<T>(); public void PrintList() { foreach(var item in Cache) { Console.WriteLine(item); } } } public class Bar : Foo<Bar> { public Bar() { Cache.Add(this); } } public class Baz : Foo<Baz> { public Baz() { Cache.Add(this); } } 
0
source

try the following:

 using System.Collections.Generic; using System; 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); System.Console.ReadKey(); } } public abstract class Foo { public Foo() { Cache = new List<string>(); } public List<String> Cache { get; set; } } public class Bar : Foo { public Bar() { Cache.Add("Bar"); } } public class Baz : Foo { public Baz() { Cache.Add("Baz"); } } 

Sorry, I had to change the case. It made my head explode

-1
source

All Articles