John Connor
John Connor

Reputation: 1

Is there any way to know when a method calling finished?

For the question, let's say:

public class Animal
{
  public Animal Play() {}

  public Animal Eat() {}

  public void Sleep() {/*Do something*/}
}

class Main
{
  var dog = new Animal();
  dog.Play().Eat();
}

Is there any way for the Sleep() method to be invoked each time a method in Animal class was called? It's a kind of TestCleanUp attribute in the Unit Test but this is just for a normal method.

Upvotes: 0

Views: 123

Answers (4)

InBetween
InBetween

Reputation: 32760

I'm guessing that your exact scenario is a little more convoluted and you are probably thinking in some class hierarchy where you need to ensure or enforce that a certain method is called always in certain circumstances. Otherwise, the solution is completely trivial as Rahul's answer desmonstrates.

You can enforce always calling Sleep using the following nifty pattern:

public abstract class Animal
{
     public void Sleep() { .... }

     public Animal Eat()
     {
         OnEat();
         Sleep();
     }

     public Animal Play();
     {
         OnPlay();
         Sleep();
     }

     protected abstract Animal OnEat();
     protected abstract Animal OnPlay();
}

Now any "nice and behaved" class deriving from Animal must implement OnEat and OnPlay and Sleep is guaranteed to be called when calling Eat or Play. You can even make Sleep virtual if implementation can differ from one derived class to another.

Of course nothing is preventing a derived class from being nasty:

public class SomewhatEvilDog: Animal
{
     protected override Animal OnEat() { ... }
     protected override Animal OnPlay() { ... }

     public new Animal Eat() { OnEat(); }
     public new Animal Play() { OnPlay(); }
}

And now the following wont call Sleep() and our world is lost and doomed:

SomewhatEvilDog dog = new SomewhatEvilDog();
dog.Eat(); //will NOT call Sleep()
dog.Sleep(); //will NOT call Sleep()

But its not all bad news; SomewhatEvilDog will have no choice but to behave if the code is the following:

Animal = new SomewhatEvilDog();
dog.Eat(); //will call Sleep()
dog.Sleep(); //will call Sleep()

Upvotes: 0

Mikael Puusaari
Mikael Puusaari

Reputation: 1034

No, the class is just a class, you need to call the Sleep() method of the Animal class

But you should make the Animal Class an interface and create a class called Dog that inherits from the Animal Interface for better readability, then create an instance of it:

var dog = new Dog();

and then call the dog.Sleep() method

To always have the Sleep() method being invoked, you need to call the method, for example, if you want it to be invoked each time the dog has eaten, put the call for the sleep method in the end of the Eat() method:

  public void Eat() 
  {
   //Your eat code
   Sleep();
  }

Upvotes: 0

Rahul
Rahul

Reputation: 77876

Is there any way for the Sleep() method to be invoked each time a method in Animal class was called?

Yes, call that method in all member and make Sleep() a private method rather since there probably won't be any outside consumer of it.

  public Animal Play() { this.Sleep();}

  public Animal Eat() { this.Sleep();}

  private void Sleep() {/*Do something*/}

Upvotes: 0

Offir
Offir

Reputation: 3491

public class Animal
{
  public Animal Play() 
  {
    //Do somthing...
    Sleep();
  }

  public Animal Eat() 
  {
    //Do somthing...
    Sleep();
  }

  public void Sleep() {/*Do something*/}
}

class Main
{
  var dog = new Animal();
  dog.Play().Eat();
}

Upvotes: 1

Related Questions