2010-08-03 3 views
3

У меня есть класс абзаца с именем Организм, у которого есть Дата рождения Событие. Также у меня есть некоторые классы, которые наследуют класс ... Так что мой вопрос: как я могу поднять событие среди всех экземпляров всех классов, унаследовавших класс Organism?Поднять событие среди всех экземпляров класса

EDIT: К сожалению, мероприятие, я хотел написать был Tick не родился ... Борн событие уровня экземпляра ...

ответ

0

Это не большой, но это может работать:

public abstract class Organism : IDisposable 
{ 
    private static readonly List<Organism> LiveOrganisms = 
     new List<Organism>(); 

    private event EventHandler onBorn; 

    public void InvokeBorn(EventArgs e) 
    { 

     foreach (var liveOrganism in LiveOrganisms 
      .Where(liveOrganism => liveOrganism.onBorn != null)) 
     { 
      liveOrganism.onBorn(this, e); 
     } 
    } 

    public event EventHandler Born 
{ 
    add 
    { 
     onBorn += value; 
    } 
    remove 
    { 
     onBorn -= value; 
    } 
} 

    protected Organism() 
    { 
     LiveOrganisms.Add(this); 
    } 

    public void Dispose() 
    { 
     LiveOrganisms.Remove(this); 
    } 
} 
+0

IMO событие уровня экземпляра и InvokeBorn не имеет большого смысла. Чувствуется ... странно ... иметь метод уровня экземпляра, который затрагивает больше случаев, чем сам. Не лучше ли статическое событие и метод? – dtb

+0

@dtb: Вы правы, это кажется странным. Но я, хотя он действительно описал функциональность, заданную в вопросе. Я не могу думать о хорошем случае для этого в целом. –

+0

Извините, событие, которое я намеревался написать, было Tick Not Born ... Born - событие уровня экземпляра ... –

0

Там нет никакого способа, чтобы получить список всех экземпляров некоторого класса , так что вы должны следить за новыми экземплярами себя:

List<Organism> organisms = new List<Organism>(); 

Organism bob = new Amoeba(); 
organisms.Add(bob); 

Позже вы можете перебирать свой список экземпляров и сделать их всех поднять событие, один за другим:

foreach (Organism organism in organisms) 
{ 
    organism.Awake(); 
} 
+0

И логичное место для organisms.Add() будет конструктор Организм. –

+0

@ Хенк: Я думал об этом, но разрушение объекта было бы сложным. Возможно реализовать IDisposable, который удалит их из статического списка, чтобы они могли быть удалены. –

+0

@ Хенк: Может быть. Возможно, нет. Фактически, я изо всех сил пытался найти доброе имя для метода, который вдыхает жизнь в организм и вызывает событие «Born». Вы «рождаетесь» или «рожаете», вы не становитесь волшебным живым. Может быть, родительский организм должен иметь способ родить новый детский организм? :) – dtb

2
public class Organism : IDisposable 
{ 
    public static List<Organism> All = new List<Organism>(); 

    private bool disposed = false; 

    public Organism() 
    { 
     Organism.All.Add(this); 
    } 

    public void BeBorn() 
    { 
     throw new NotImplementedException(); 
    } 

    public void Dispose() 
    { 
     Dispose(true); 

     GC.SuppressFinalize(this); 
    } 

    private void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       Organism.All.Remove(this); 
      } 

      disposed = true; 
     } 
    } 

~Organism() 
    { 
     Dispose(false); 
    } 

} 
+0

Является ли статическое событие действительно хорошей идеей? – dtb

+0

Возможно, не обязательно для события, но статический список или какой-то статичный, который каждый Организм регистрирует при строительстве, будет правильным путем. –

+3

Обратите внимание, что событие будет «защищать» организмы от GC, точно так же, как Список будет. A Dispose() в порядке, а также руководство по его использованию. –

0

Почему бы не каждый конкретный организм вызывать его родителя рождения когда он рожден. Что-то вроде:

public abstract class Organism 
{ 
    public event EventHandler<EventArgs> Born; 
    public string Name { get; set; } 

    public Organism() 
    { 
    } 

    public void Birth() 
    { 
     this.raiseBorn(new EventArgs()); 
    } 

    protected void raiseBorn(EventArgs args) 
    { 
     EventHandler<EventArgs> handler = this.Born; 
     if (handler != null) 
      handler(this, args); 
    } 
} 

// Concrete organisms ========-------- 

public class Dog : Organism 
{ 
    public Dog() 
    { 
     this.Name = "Dog"; 
    } 

    public override string ToString() 
    { 
     return this.Name; 
    } 
} 

public class Cat : Organism 
{ 
    public Cat() 
    { 
     this.Name = "Cat"; 
    } 

    public override string ToString() 
    { 
     return this.Name; 
    } 
} 

// Creature Factory ========-------- 

public class CreatureCreator : List<Organism> 
{ 
    public event EventHandler<BornArgs> CreaturBorn; 
    private void raiseCreatureBorn(BornArgs args) 
    { 
     EventHandler<BornArgs> handler = this.CreaturBorn; 
     if (handler != null) 
      handler(this.CreaturBorn, args); 
    } 

    public void CreateCreature<T>() where T : Organism, new() 
    { 
     Organism o = new T(); 
     o.Born += o_Born; 
     this.Add(o); 

     o.Birth(); 
    } 

    private void o_Born(object sender, EventArgs e) 
    { 
     this.raiseCreatureBorn(new BornArgs((Organism)sender)); 
    } 
} 

public class BornArgs : EventArgs 
{ 
    public Organism Creature { get; set; } 

    public BornArgs(Organism o) 
    { 
     this.Creature = o; 
    } 
} 

// Usage ========-------- 

static void Main(string[] args) 
{ 
    CreatureCreator deity = new CreatureCreator(); 
    deity.CreaturBorn += deity_CreaturBorn; 

    deity.CreateCreature<Dog>(); 
    deity.CreateCreature<Cat>(); 

    Console.ReadKey(); 
} 

static void deity_CreaturBorn(object sender, BornArgs e) 
{ 
    Console.WriteLine(e.Creature.ToString() + " was born"); 
} 

выход:

 
Dog was born 
Cat was born 
+0

Проблема в том, что я написал Born вместо Tick ... –

Смежные вопросы