2017-02-20 7 views
0

これは概念的な質問です。私は抽象的なベースマネージャーを持っており、ベースクラスにDispatcherTimerを定義しました。私は4人のマネージャーによって私のベースマネージャーを継承します。問題は、childマネージャのインスタンスを作成するたびに、Baseマネージャの新しいインスタンスが作成されますか?そして、4つのタイマーが宣言されているのでしょうか?私はこれが些細な質問かもしれないことを知っていますが、私はちょっとそれに巻き込まれました。抽象基底クラスで定義されたオブジェクトは、その都度固有のインスタンスを作成しますか?

+0

サンプルコードを追加するのはどうですか?そして、あなたがシングルトンにしない限り、それぞれの「子供」はタイマーの独自のインスタンスを持ちます。 –

+1

'Base'コンストラクタにいくつかのロギング/デバッグプリントを追加して、デバッガで一歩一歩歩いてください。 – doctorlove

+0

興味がありません - なぜ尋ねますか?あなたのタイマーはすべて同じタイミングで発砲していますか? – doctorlove

答えて

1

子クラスのそれぞれの新しいインスタンスもベースクラスのインスタンスです。ベースのインスタンスが4つあり、それぞれ別々のタイマーがあります。インスタンス間でタイマーを共有する場合は、スタティックとマークします。

更新

あなたはこのようにタイマーインスタンスを共有することができます。

class Class1 
{ 
    void DoSomething() 
    { 
     var timer = new DispatcherTimer(); 
     var m1 = new Manager(timer); 
     var m2 = new Manager(timer); 
     var m3 = new Manager(timer); 
     var m4 = new Manager(timer); 
    } 
} 

abstract class BaseManager 
{ 
    protected abstract void Timer_Tick(object sender, object e); 

    protected BaseManager(DispatcherTimer timer) 
    { 
     timer.Tick += Timer_Tick; 
    } 
} 

class Manager: BaseManager 
{ 
    public Manager(DispatcherTimer timer) 
    : base(timer) { } 

    protected override void Timer_Tick(object sender, object e) 
    { 
     throw new NotImplementedException(); 
    } 
} 

更新

あなたはIOCコンテナを使用している場合は、の共有インスタンスを持つことができますこのようなインターフェース:

interface IMangerTimer 
{ 
    DispatcherTimer Timer { get; } 
} 

class ManagerTimer : IMangerTimer 
{ 
    public DispatcherTimer Timer { get; } = new DispatcherTimer(); 
} 

abstract class BaseManager 
{ 
    protected abstract void Timer_Tick(object sender, object e); 

    protected BaseManager(IMangerTimer timer) 
    { 
     timer.Timer.Tick += Timer_Tick; 
    } 
} 

そうでない場合は、インターフェイスを削除して、ManagerTimerクラスを静的にしてください。

+0

はい、私はそれについて考えていました、問題は、それはdispatcherTimerであり、静的になるTickイベント。 tickメソッドはオーバーライドされたrefreshメソッドを呼び出すので、タイマーを静的にすることはできません。 –

+1

他のどこかの単一のタイマーを作成し、それを使用したい他のオブジェクトのコンストラクタに渡します。 – doctorlove

+0

@doctorloveは、作成されたインスタンスを減らすために、タイマーをインターフェイスに配置しますか?ベースマネージャーは抽象クラス –

0

は、次のコードを取る:

public class FooBase { } 
public class Foo: FooBase { } 

を今すぐあなたが行うときは、次の

var foo = new Foo(); 

だけインスタンスが作成されます。継承はあるので今、関係「である」、次の代入は有効です。

FooBase fooAsBase = foo; 

が新しいFooが作成されると、すべてのロジックは、FooBaseを作成するために必要なことを、心に留めておくかもされます2つの異なるオブジェクトが生成されているわけではありません。 new Foo()では、パラメータなしコンストラクタFoo impliciltyは、パラメータなしコンストラクタをFooBaseに呼び出します。

UPDATE:あなたのコメントに基づき、もう少し例を開発することができます:今

public class FooBase 
{ 
    Bar someField = new Bar(); 
} 

public class Foo: FooBase { } 

、次のコードを与えられた:

var foo1 = new Foo(); 
var foo2 = new Foo(); 

foo1Barオブジェクトへの参照を保持しますfoo2は完全に異なるBarオブジェクトへの参照を保持します。

+0

もし私が4人の子マネージャーを1人の抽象基本マネージャーから継承したら、4つのdispatcherTimersが作成されますか? Tickイベントのための独自の実装を持つそれぞれは? –

+0

@AdityaSharma基本クラスを継承するフォームの種類はいくつですか? 'dispatcherTimers'がもちろん静的でない限り、あなたが作成する子マネージャーのインスタンスと同じくらい多くの' dispatcherTimers'を持っています。私の答えへの更新を見てください。 – InBetween

+0

はいそれを静的にすることは私の心に浮かびましたが、問題はスタティックタイマーが静的なチックイベントを持つことです。そして、それぞれの子マネージャーは、それ自身がtickイベントを実装する必要があります。だから、私のタイマーが抽象的なベースマネージャーにあり、そのタイマーイベントで呼び出され、抽象メソッドを呼び出すのです。 –

1

@ InBetweenの答えで展開し、インスタンスを構築時に共有リストに追加するコードを追加しました。

public class FooBase 
{ 
    private static List<FooBase> _instances = new List<FooBase>(); 

    public FooBase() 
    { 
     _instanves.Add(this); 
    } 
} 

public class Foo: FooBase { } 

Fooのデフォルトコンストラクタが暗黙的にリストに現在のインスタンスを追加しますFooBaseのデフォルトコンストラクタを呼び出します。

範囲外になるオブジェクトとしてリストを管理するのは難しい場合があります。最も簡単な方法は、インスタンスを明示的に削除するメソッドを追加することですが、常にそれを呼び出すことについては非常に厳格でなければなりません。もう1つの選択肢はIDisposableを実装してそこのインスタンスを削除することですが、それは問題の全体を開くことができます。

+0

私は自分の答えをどこに広げているのかは分かりません。この問題を解決するために静的なフィールドやリストを使用することは間違いありません。私がこれを行う方法は、コンストラクタにタイマー(またはタイマープロバイダ)を注入することです。 – InBetween

+0

そのため、リストにはベースが何回も組み込まれていても1回だけ作成されます。 –

+0

@AdityaSharmaはい、正確です。その後、あなたのタイマーも静的になり、 'FooBase'のリストにアクセスしてループします。あなたは、それぞれの個々の 'FooBase'であなたが望むものを呼び出すことができます。これはおそらくこれを行うための最良の方法ではありません、私はおそらくそれを行うことをお勧めしません。これは可能なことを説明するためのものです。 –

関連する問題