抽象基本クラスまたはインターフェース?どちらも正しくないようです
-
03-07-2019 - |
質問
次のコードを指定します:
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); }
}
(やや予想される)出力が得られます&quot; 2本のバーがあります、喜んでください!&quot;。
これは素晴らしいことです。ビールを飲む場所が2倍になりました(明らかに)。しかし、私が本当に欲しいのは、各クラスが独自のキャッシュを持つことです。このキャッシュをサブクラスに実装したくないのは、抽象クラスにいくつかのメソッドがあり、これらのメソッドはキャッシュを操作できるようにする必要があるためです(つまり、すべてを反復処理するため)。これを行う方法はありますか? foo
のインターフェースの使用を検討しましたが、このインターフェースでは、静的メンバーをインターフェースの一部として定義することはできません。
解決
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 { }
他のヒント
サブクラスでパラメーター化された汎用基本クラスを使用します。
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); }
}
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); }
}
答えは次のとおりです。
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); }
}
これを試してください:
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"); }
}
申し訳ありませんが、ケーシングを変更する必要がありました。それは私の頭を爆発させていました
所属していません StackOverflow