2009-03-05 17 views
4

次のコードを考える:抽象基本クラスまたはインタフェース?どちらも思えない右

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); } 
} 

をあなたが(多少期待される)出力を得る「私たちは喜ぶ、2つのバーを持っているの!」。

これはすごく面白いですが、私たちはビールを飲む場所を2倍に増やしました(明らかに)が、本当に欲しいのは、各クラスが自分のキャッシュを持つことです。私がサブクラスでこのキャッシュを実装したくない理由は、キャッシュ上で操作できる(つまり、それらのすべてを反復する)必要がある抽象クラスにいくつかのメソッドがあるためです。これを行う方法はありますか?私はfooのインターフェイスを使用してみましたが、インターフェイスで静的メンバーをインターフェイスの一部として定義することはできません。ここで

答えて

8

fooの各派生クラスは、キャッシュを取得する方法と場所を定義する必要があります。したがって、それぞれのキャッシュは(潜在的に)独自のキャッシュを持つことができます。 fooのメソッドは、実装がわからずにGetCache()を参照できます。

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 { } 
+0

「新しい回答を読み込む」機能があります。私はこれを掲載しようとしていた。 – moffdub

+0

ICacheは一般的なキャッシュタイプへのインターフェイスですか?実際には、あなたが正しいと思っていますが、thinkcubeの答えが私が最初に探していたものに近いものの、私はこれがより好きです。これは私が今でもやるより多くの設計作業です;) –

+1

私はこれがより良いことに同意します。それぞれのサブクラスは、独自のシングルトンを提供することを心配する必要があります。コードの複製の潜在性代わりにジェネリックを使用して、クラスごとのシングルトンを取得し、GetCache()を使用して一度公開することはできますが、各サブクラスはそれを実装する必要はありません。 –

0

は、あなたの答えです:

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

これは、そのタイプのすべてのオブジェクトのキャッシュです。それが非静的であれば、どのように機能しますか? –

+0

"私が本当に望むのは、各クラスが自分のキャッシュを持っていることです" - あなたはそうしている、あるいはしていない。一つを選ぶ。 –

+0

各クラスであり、それぞれのインスタンスではありません。 –

-1

はこれを試してください:私はケースを変更しなければならなかった

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"); } 
} 

申し訳ありません...それは私の頭が

1
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); } 
} 
+0

Arg、それに私を打つ。私の正確なアイデア。 – strager

4

がジェネリックを使用して爆発作っていましたサブクラスでパラメータ化された基底クラス:

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); } 
} 
+0

非常に良い、よかった! –

+0

バー、6分で私を打つ。良いショー。 –

+0

これはおそらく次のようになるはずです:public abstract class foo ここでT:foo

関連する問題