Vadim
Vadim

Reputation: 414

Reference a code

I'm wondering if this is possible to do in c#.

Let's say i have a class with these methods:

public class Ladder
{
    private int currentStep = 0;

    Ladder Up()
    {
        currentStep++;
        return this;
    }

    Ladder Down()
    {
        currentStep--;
        return this;
    }
}

I can use it like this:

Ladder ladder = new Ladder();

ladder.Up().Up().Up().Down().Down();

Now, I would like to add a conditional method, that could be used like this:

ladder.IF(somecondition, Up(), Down());

Meaning if somecondition == true then execute Up(), else Down()

Is it possible to do? I was thinking about using anonymous methods, but can't figure out how to reference "this" instance so it would know what that these functions are referred to.

Any help is greatly appreciated!

Upvotes: 3

Views: 144

Answers (6)

DKH
DKH

Reputation: 462

You can add another method in your Ladder class (with : using System.Reflection; )

public Ladder IF(bool condition, string trueFunc, string falseFunc)
{
    MethodInfo trueMethod = this.GetType().GetMethod(trueFunc);
    MethodInfo falseMethod = this.GetType().GetMethod(falseFunc);
    return condition ? (Ladder)trueMethod.Invoke(this, null) : (Ladder)falseMethod.Invoke(this, null);
}

And use it like that :

ladder.IF(true, "Up", "Down"); // goes up
ladder.IF(false, "Up", "Down"); // goes down
ladder.IF(true, "Down", "Up"); // goes down
ladder.IF(false, "Down", "Up"); // goes up

Upvotes: 0

RB.
RB.

Reputation: 37172

This is the closest I could get to what you want - there is an extension method called If which takes actions to perform on the ladder. These actions are defined in your Ladder class as static methods. Then you use the static import functionality to import your Ladder class.

// This import is really important - it lets you refer to Up, 
// rather than Ladder.Up.
using static Ladder;

void Main()
{
    Ladder ladder = new Ladder();

    // Basic usage
    ladder.If(true, Up, Down);
    Console.WriteLine(ladder.ToString());

    // And demonstrating chaining.
    ladder.If(false, Up, Down).If(false, Up, Down);
    Console.WriteLine(ladder.ToString());
}

public class Ladder
{
    private int currentStep = 0;

    public Ladder Up()
    {
        currentStep++;
        return this;
    }

    public Ladder Down()
    {
        currentStep--;
        return this;
    }

    // Static methods for Up and Down a ladder.
    public static void Up(Ladder ladder)
    {
        ladder.Up();
    }

    public static void Down(Ladder ladder)
    {
        ladder.Down();
    }

    public override string ToString()
    {
        return "I'm on step " + currentStep;
    }
}


public static class Extensions
{
    // Extension method to conditionally take an action on the ladder.
    public static Ladder If(this Ladder ladder, bool condition, Action<Ladder> trueAction, Action<Ladder> falseAction)
    {
        if (condition)
        {
            trueAction(ladder);
        }
        else
        {
            falseAction(ladder);
        }

        return ladder;
    }
}

Upvotes: 0

Aboc
Aboc

Reputation: 237

This is the way to write this method :

public Ladder If(bool someCondition, Func<Ladder> trueFunc, Func<Ladder> falseFunc)
    {
        return someCondition ? trueFunc() : falseFunc();
    }

And the way to call it is

ladder.If(condition, ladder.Up, ladder.Down);

Upvotes: 2

vgru
vgru

Reputation: 51204

This would probably be close to what you're asking, although I wouldn't say it will make the code clearer to future maintainers:

Ladder If(bool condition,
    Func<Ladder, Ladder> @true, 
    Func<Ladder, Ladder> @false)
{
    return condition ? @true(this) : @false(this);
}

Usage:

ladder
    .Up()
    .Down()
    .If(true, l => l.Up(), l => l.Down())
    .Up()
    .Down();

Upvotes: 5

Jamiec
Jamiec

Reputation: 136074

You could add another method Go which encapsulates your requirement, you have 2 options - perhaps implement both:

public Ladder Go(bool condition)
{
    if(condition)
      Up();
    else
      Down();
    return this;
}

public Ladder Go(Func<bool> condition)
{
    return this.Go(condition());
}

This allows you to specify a boolean, inline a condition, or pass a function

ladder.Go(true);
ladder.Go(someValue > 0);
ladder.Go( someMethodWhichTakesNoParamsAndReturnsBool )

Upvotes: 2

Romano Zumb&#233;
Romano Zumb&#233;

Reputation: 8079

You don't need a conditional method. Use the ?: operator:

somecondition ? ladder.Up() : ladder.Down();

Upvotes: 3

Related Questions