Ryan A WE
Ryan A WE

Reputation: 59

C# Why can't interfaces implement methods like this? What is a workaround to solve my issue?

Why can't interfaces implement methods like this?

public interface ITargetableUnit {
        //Returns whether the object of a class that implements this interface is targetable
     bool unitCanBeTargeted(){
        bool targetable = false;
        if(this is Insect){
            targetable = (this as Insect).isFasterThanLight();
        }
        else if(this is FighterJet){
            targetable = !(this as FighterJet).Flying;
        }
        else if(this is Zombie){
            targetable = !(this as Zombie).Invisible;
        }
        return targetable;
    }
}

Insect, and Zombie all already derives from base class Creature, and FighterJet derives from class Machine However, not all Creature-s are targetable and do not use ITargetableUnit inteface.

Is there any workaround to solve the issue that I am facing?

Upvotes: 0

Views: 130

Answers (3)

mybirthname
mybirthname

Reputation: 18127

Like everybody said you can't define behaviour for interfaces. Inherite the interface to the specific classes.

public interface ITargetableUnit 
{

     bool unitCanBeTargeted();

}

public class Insect : ITargetableUnit //you can add other interfaces here
{

     public bool unitCanBeTarget()
     {
          return isFasterThanLight();
     }
}

public class Ghost : ITargetableUnit 
{
     public bool unitCanBeTarget()
     {
          return !Flying();
     }
}

public class Zombie : ItargetableUnit
{
     public bool unitCanBeTarget()
     {
          return !Invisible();
     }
}

Upvotes: 7

Karsten Gutjahr
Karsten Gutjahr

Reputation: 354

Maybe you want an abstract class and not an interface?

Interfaces define what methods a class provides. Abstract classes do this as well but can also take over some calculations for every child.

Please be aware that from a technical perspective an Insect can also be a Zombie.

Happy coding!

public abstract class TargetableUnit
{
    //Returns whether the object of a class that implements this interface is targetable
    public bool unitCanBeTargeted()
    {
        bool targetable = false;
        if (this is Insect)
        {
            targetable = (this as Insect).isFasterThanLight();
        }
        else if (this is FighterJet)
        {
            targetable = !(this as FighterJet).Flying;
        }
        else if (this is Zombie)
        {
            targetable = !(this as Zombie).Invisible;
        }

        return targetable;
    }
}

public class Insect : TargetableUnit
{
    public bool isFasterThanLight()
    {
        return System.DateTime.UtcNow.Second == 0;
    }
}
public class FighterJet : TargetableUnit
{
    public bool Flying { get; set; }
}
public class Zombie : TargetableUnit
{
    public bool Invisible { get; set; }
}

Upvotes: 1

CSharpie
CSharpie

Reputation: 9467

Just for the record, you can actually do this (DONT!) but this isnt considered a good practice to make extensionmethods for code you have acces to. Mybirthname's solution is the way to go, this is just for demonstration.

public interface ITargetableUnit { }


public static class ITargetableUnitExtension
{

    public static bool unitCanBeTargeted(this ITargetableUnit unit)
    {
        bool targetable = false;
        Insect insect = unit as Insect;
        if(insect != null)
            return insect.isFasterThanLight();
        FighterJet jet = unit as FighterJet;
        if(jet != null)
            return !jet.Flying;
        Zombie zombie = unit as Zombie;
        if(zombie != null)
            return zombie.Invisible;
        return false;
    }
}

Upvotes: 1

Related Questions