Chain IFs and execute first one to fail.

S

Shapper

Hello,

I am trying to do the following:

MyObject.If(x => x.ID == 10, new MyAction("ID10")).If(x => x.Value < 20, new MyAction("Value20")).DoSomethingWithMyAction();

MyObject is an object with a few properties which I need to check ...

DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.

It could be something like:

public static If<T>(this T myobject, Func<T, Boolean> predicate, MyAction action) where T : MyObject {

if (predicate(myobject)
// Return ??? >> Move to Next If
else
// Return action

} // If

Then DoSomethingWithMyAction() would simply be a MyAction extension.

My problems are:
1 - How to chain the IFs;
2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

Thank You,
Miguel
 
S

Shapper

On Fri, 20 Jul 2012 10:44:17 -0700 (PDT), Shapper wrote:

&gt; Hello,
&gt;
&gt; I am trying to do the following:
&gt;
&gt; MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
&gt;
&gt; MyObject is an object with a few properties which I need to check ...
&gt;
&gt; DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.

Sounds like you need for the If() methods to accumulate the predicates and
MyAction objects, e.g. into a List&lt;T&gt;. Then calling
DoSomthingWithMyAction() would actually retrieve that list somehow,
invoking the delegates and testing the predicate results to determine which
MyAction object to return.

You might also want to consider making the second argument of the If()
method a factory delegate instance, rather than actually creating the
MyAction object to be passed to the If() method. That way you only actually
allocate the MyAction object you really want.

Without knowing more about the exact types and your control over them, it's
hard to say exactly how you'd implement the accumulation. But basically,
you just need a consistent place where the List&lt;T&gt; that contains your
predicate and result data, presumably in whatever the If() method returns.

You may be able to apply the decorator pattern along with an explicit
conversion in a generic type to support the If() method.

Pete

Hello,

I was trying accumulation with yield ... But I have been able to figure this out.

I will try to explain better the exact types and give an example:

I am receiving Agatha Responses:
https://github.com/davybrion/Agatha/blob/master/Agatha.Common/Response.cs

So my responses are for example:

public class FindUserByIdResponse : Response { }
public class CreatedUserResponse : Response { }

When I receive a Response I need to test a few conditions.

Each condition will have an ActionResult associated with it:
http://msdn.microsoft.com/en-us/library/system.web.mvc.actionresult.aspx

So the first condition to fail will Execute that action result.
If no condition fails then no ActionResult will be executed.

So the code:

FindUserByIdResponse response = _service.FindUserById(418);

if (response == null)
VoidActionResult().Execute();
if (response.User == null)
NotFoundActionResult().Execute();
....

This would become something like:

FindUserByIdResponse response = _service.FindUserById(418);

response.If(x => x == null, VoidActionResult()).If(x => x.User == null, NotFoundActionResult()).Execute();

I am not sure if I need to use <FindUserByIdResponse> after the If.
I need to check some of its properties which differ from Response to Response (FindUserByIdResponse, CreateUserByIdResponse, etc ...).

But I am not sure if there is a way to not include <...> in every If ...

Basically that is what I am trying to do ...

Any idea?
 
A

Arne Vajhøj

I am trying to do the following:

MyObject.If(x => x.ID == 10, new MyAction("ID10")).If(x => x.Value < 20, new MyAction("Value20")).DoSomethingWithMyAction();

MyObject is an object with a few properties which I need to check ...

DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.

It could be something like:

public static If<T>(this T myobject, Func<T, Boolean> predicate, MyAction action) where T : MyObject {

if (predicate(myobject)
// Return ??? >> Move to Next If
else
// Return action

} // If

Then DoSomethingWithMyAction() would simply be a MyAction extension.

My problems are:
1 - How to chain the IFs;
2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

My suggestion:

public static class Extensions
{
public static Tuple<T, MyAction> If<T>(this Tuple<T, MyAction>
prev, Func<T, bool> f, MyAction action)
{
return prev.Item2 == null ? new Tuple<T,
MyAction>(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple<T, MyAction> If<T>(this T o, Func<T, bool>
f, MyAction action)
{
return new Tuple<T, MyAction>(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction<T>(this Tuple<T,
MyAction> res)
{
Console.WriteLine(res.Item2 == null ? "No ifs" :
res.Item2.Text);
}
}

Demo:

using System;

namespace E
{
public class MyAction
{
public string Text { get; set; }
public MyAction(string msg)
{
Text = msg;
}
}
public class Something
{
public int ID { get; set; }
public int Value { get; set; }
}
public class SomethingElse
{
public string S { get; set; }
}
public static class Extensions
{
public static Tuple<T, MyAction> If<T>(this Tuple<T, MyAction>
prev, Func<T, bool> f, MyAction action)
{
return prev.Item2 == null ? new Tuple<T,
MyAction>(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple<T, MyAction> If<T>(this T o, Func<T, bool>
f, MyAction action)
{
return new Tuple<T, MyAction>(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction<T>(this Tuple<T,
MyAction> res)
{
Console.WriteLine(res.Item2 == null ? "No ifs" :
res.Item2.Text);
}
}
public class Program
{
public static void Main(string[] args)
{
Something o = new Something { ID = 10, Value = 10 };
o.If(x => x.ID == 10, new MyAction("ID10")).If(x => x.Value
< 20, new MyAction("Value20")).DoSomethingWithMyAction();
SomethingElse o2 = new SomethingElse { S = "ABC" };
o2.If(x => x.S == "A", new
MyAction("AA")).DoSomethingWithMyAction();
Console.ReadKey();
}
}
}

Arne
 
S

Shapper

On Fri, 20 Jul 2012 10:44:17 -0700 (PDT), Shapper wrote:

&gt; [...]
&gt; My problems are:
&gt; 1 - How to chain the IFs;
&gt; 2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

I'm still not entirely sure I understand the real-world scenario you're
trying to address, but here's a short code example that implements what you
seem to be asking for.

Note that I went ahead with the factory delegate suggestion. But as long
as the type being returned has a simple constructor with little overhead
(i.e. it's just storing the values of the arguments passed), then there
should be no trouble allocating individual objects for each call to If()
rather than supplying a factory delegate instance instead.


using System;

namespace TestIteratedIf
{
static class Extensions
{
public static A&lt;T, U&gt; If&lt;T, U&gt;(this T t, Func&lt;T, bool&gt; predicate,
Func&lt;U&gt; factory)
{
return new A&lt;T, U&gt;(t, predicate, factory);
}

public static A&lt;T, U&gt; If&lt;T, U&gt;(this A&lt;T, U&gt; a, Func&lt;T, bool&gt;
predicate, Func&lt;U&gt; factory)
{
return new A&lt;T, U&gt;(a, predicate, factory);
}

public static void DoSomething&lt;T&gt;(this A&lt;T, MyAction&lt;T&gt;&gt; a)
{
a.Evaluate().Do();
}
}

class A&lt;T, U&gt;
{
private A&lt;T, U&gt; _previous;
private T _data;
private Func&lt;T, bool&gt; _predicate;
private Func&lt;U&gt; _factory;

public A(A&lt;T, U&gt; previous, Func&lt;T, bool&gt; predicate, Func&lt;U&gt;
factory)
: this(previous, previous._data, predicate, factory)
{ }

public A(T data, Func&lt;T, bool&gt; predicate, Func&lt;U&gt; factory)
: this(null, data, predicate, factory)
{ }

private A(A&lt;T, U&gt; previous, T data, Func&lt;T, bool&gt; predicate,
Func&lt;U&gt; factory)
{
_previous = previous;
_data = data;
_predicate = predicate;
_factory = factory;
}

public U Evaluate()
{
U result;

if (!_Do(this, out result))
{
throw new Exception(&quot;No predicate failed&quot;);
}

return result;
}

private bool _Do(A&lt;T, U&gt; current, out U result)
{
result = default(U);

if (current == null)
{
return false;
}

if (_Do(current._previous, out result))
{
return true;
}

bool stop = !current._predicate(current._data);

if (stop)
{
result = current._factory();
}

return stop;
}
}

class MyAction&lt;T&gt;
{
public T Data { get; private set; }
public string Format { get; private set; }

public MyAction(T data, string format)
{
Data = data;
Format = format;
}

public void Do()
{
Console.WriteLine(Format, Data);
}
}


class Program
{
static void Main(string[] args)
{
try
{
Method(5);
Method(10);
Method(17);
Method(20);
}
catch (Exception e)
{
Console.WriteLine(&quot;Exception: {0}&quot;, e);
}
}

static void Method(int value)
{
value.If(i =&gt; i &gt; 5, () =&gt; new MyAction&lt;int&gt;(value, &quot;{0} first
action&quot;))
.If(i =&gt; i &gt; 10, () =&gt; new MyAction&lt;int&gt;(value, &quot;{0} second
action&quot;))
.If(i =&gt; i &gt; 17, () =&gt; new MyAction&lt;int&gt;(value, &quot;{0} third
action&quot;))
.DoSomething();
}
}
}

Hello Peter,

I have been trying your code but I have a problem:

MyClass value = new MyClass { Id = 6 };

value
.If(i => i.Id > 5, () => new MyAction<int>(value, "{0} first action"))
.If(i => i.Id > 10, () => new MyAction<int>(value, "{0} second action"))
.If(i => i > 17, () => new MyAction<int>(value, "{0} third action"))
.DoSomething();

On the second If "i" is of type A ... And I need to keep testing MyClass.

So i.Id > 10 is not accepted ...

I removed the factory. No need for that in that case.
 
S

Shapper

On 7/20/2012 1:44 PM, Shapper wrote:
&gt; I am trying to do the following:
&gt;
&gt; MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
&gt;
&gt; MyObject is an object with a few properties which I need to check ....
&gt;
&gt; DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.
&gt;
&gt; It could be something like:
&gt;
&gt; public static If&lt;T&gt;(this T myobject, Func&lt;T, Boolean&gt;predicate, MyAction action) where T : MyObject {
&gt;
&gt; if (predicate(myobject)
&gt; // Return ??? &gt;&gt; Move to Next If
&gt; else
&gt; // Return action
&gt;
&gt; } // If
&gt;
&gt; Then DoSomethingWithMyAction() would simply be a MyAction extension.
&gt;
&gt; My problems are:
&gt; 1 - How to chain the IFs;
&gt; 2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

My suggestion:

public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot;:
res.Item2.Text);
}
}

Demo:

using System;

namespace E
{
public class MyAction
{
public string Text { get; set; }
public MyAction(string msg)
{
Text = msg;
}
}
public class Something
{
public int ID { get; set; }
public int Value { get; set; }
}
public class SomethingElse
{
public string S { get; set; }
}
public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot;:
res.Item2.Text);
}
}
public class Program
{
public static void Main(string[] args)
{
Something o = new Something { ID = 10, Value = 10 };
o.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value
&lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
SomethingElse o2 = new SomethingElse { S = &quot;ABC&quot; };
o2.If(x =&gt; x.S == &quot;A&quot;, new
MyAction(&quot;AA&quot;)).DoSomethingWithMyAction();
Console.ReadKey();
}
}
}

Arne

Hello Arne,

I

On 7/20/2012 1:44 PM, Shapper wrote:
&gt; I am trying to do the following:
&gt;
&gt; MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
&gt;
&gt; MyObject is an object with a few properties which I need to check ....
&gt;
&gt; DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.
&gt;
&gt; It could be something like:
&gt;
&gt; public static If&lt;T&gt;(this T myobject, Func&lt;T, Boolean&gt;predicate, MyAction action) where T : MyObject {
&gt;
&gt; if (predicate(myobject)
&gt; // Return ??? &gt;&gt; Move to Next If
&gt; else
&gt; // Return action
&gt;
&gt; } // If
&gt;
&gt; Then DoSomethingWithMyAction() would simply be a MyAction extension.
&gt;
&gt; My problems are:
&gt; 1 - How to chain the IFs;
&gt; 2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

My suggestion:

public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot;:
res.Item2.Text);
}
}

Demo:

using System;

namespace E
{
public class MyAction
{
public string Text { get; set; }
public MyAction(string msg)
{
Text = msg;
}
}
public class Something
{
public int ID { get; set; }
public int Value { get; set; }
}
public class SomethingElse
{
public string S { get; set; }
}
public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot;:
res.Item2.Text);
}
}
public class Program
{
public static void Main(string[] args)
{
Something o = new Something { ID = 10, Value = 10 };
o.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value
&lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
SomethingElse o2 = new SomethingElse { S = &quot;ABC&quot; };
o2.If(x =&gt; x.S == &quot;A&quot;, new
MyAction(&quot;AA&quot;)).DoSomethingWithMyAction();
Console.ReadKey();
}
}
}

Arne

Hello,

I was trying your approach and it does what I am looking for.

But I would like to not use Tupples. Instead something like:

MyClass<T, MyAction> ...

Which is seems similar to Peter's solution ...

But I am having problems with it as I just posted.
 
S

Shapper

Hello,

I am trying to do the following:

MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();

MyObject is an object with a few properties which I need to check ...

DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.

It could be something like:

public static If&lt;T&gt;(this T myobject, Func&lt;T, Boolean&gt; predicate, MyAction action) where T : MyObject {

if (predicate(myobject)
// Return ??? &gt;&gt; Move to Next If
else
// Return action

} // If

Then DoSomethingWithMyAction() would simply be a MyAction extension.

My problems are:
1 - How to chain the IFs;
2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

Thank You,
Miguel

Hello,

This is what I am looking for:

public class A<T, U> where U : ActionResult {

private T _t;
private U _u;

public T PT { get { return _t; } }
public U PU { get { return _u; } }

public A(T t, U u) {

_t = t;
_u = u;

}

}

public static class bclass {

public static A<T, ActionResult> If<T>(this A<T, ActionResult> prev, Func<T, bool> f, ActionResult action) {

return prev.PU == null ? new A<T, ActionResult>(prev.PT, f(prev.PT) ? action : null) : prev;

}

public static A<T, ActionResult> If<T>(this T o, Func<T, bool> f, ActionResult action) {

return new A<T, ActionResult>(o, f(o) ? action : null);

}

}

It is a mix between both your suggestions.

What do you think?

Thank you,
Miguel
 
A

Arne Vajhøj

On 7/20/2012 1:44 PM, Shapper wrote:
&gt; I am trying to do the following:
&gt;
&gt; MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
&gt;
&gt; MyObject is an object with a few properties which I need to check ...
&gt;
&gt; DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.
&gt;
&gt; It could be something like:
&gt;
&gt; public static If&lt;T&gt;(this T myobject, Func&lt;T, Boolean&gt; predicate, MyAction action) where T : MyObject {
&gt;
&gt; if (predicate(myobject)
&gt; // Return ??? &gt;&gt; Move to Next If
&gt; else
&gt; // Return action
&gt;
&gt; } // If
&gt;
&gt; Then DoSomethingWithMyAction() would simply be a MyAction extension.
&gt;
&gt; My problems are:
&gt; 1 - How to chain the IFs;
&gt; 2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

My suggestion:

public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot; :
res.Item2.Text);
}
}

Demo:

using System;

namespace E
{
public class MyAction
{
public string Text { get; set; }
public MyAction(string msg)
{
Text = msg;
}
}
public class Something
{
public int ID { get; set; }
public int Value { get; set; }
}
public class SomethingElse
{
public string S { get; set; }
}
public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot; :
res.Item2.Text);
}
}
public class Program
{
public static void Main(string[] args)
{
Something o = new Something { ID = 10, Value = 10 };
o.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value
&lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
SomethingElse o2 = new SomethingElse { S = &quot;ABC&quot; };
o2.If(x =&gt; x.S == &quot;A&quot;, new
MyAction(&quot;AA&quot;)).DoSomethingWithMyAction();
Console.ReadKey();
}
}
}

Arne

Hello Arne,

I

On 7/20/2012 1:44 PM, Shapper wrote:
&gt; I am trying to do the following:
&gt;
&gt; MyObject.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value &lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
&gt;
&gt; MyObject is an object with a few properties which I need to check ...
&gt;
&gt; DoSomethingWithMyAction() is a MyAction extension that does something with the MyAction of the first condition that fails.
&gt;
&gt; It could be something like:
&gt;
&gt; public static If&lt;T&gt;(this T myobject, Func&lt;T, Boolean&gt; predicate, MyAction action) where T : MyObject {
&gt;
&gt; if (predicate(myobject)
&gt; // Return ??? &gt;&gt; Move to Next If
&gt; else
&gt; // Return action
&gt;
&gt; } // If
&gt;
&gt; Then DoSomethingWithMyAction() would simply be a MyAction extension.
&gt;
&gt; My problems are:
&gt; 1 - How to chain the IFs;
&gt; 2 - How to make DoSomethingWithMyAction() use the MyAction of the first IF to fail.

My suggestion:

public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot; :
res.Item2.Text);
}
}

Demo:

using System;

namespace E
{
public class MyAction
{
public string Text { get; set; }
public MyAction(string msg)
{
Text = msg;
}
}
public class Something
{
public int ID { get; set; }
public int Value { get; set; }
}
public class SomethingElse
{
public string S { get; set; }
}
public static class Extensions
{
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this Tuple&lt;T, MyAction&gt;
prev, Func&lt;T, bool&gt; f, MyAction action)
{
return prev.Item2 == null ? new Tuple&lt;T,
MyAction&gt;(prev.Item1, f(prev.Item1) ? action : null) : prev;
}
public static Tuple&lt;T, MyAction&gt; If&lt;T&gt;(this T o, Func&lt;T, bool&gt;
f, MyAction action)
{
return new Tuple&lt;T, MyAction&gt;(o, f(o) ? action : null);
}
public static void DoSomethingWithMyAction&lt;T&gt;(this Tuple&lt;T,
MyAction&gt; res)
{
Console.WriteLine(res.Item2 == null ? &quot;No ifs&quot; :
res.Item2.Text);
}
}
public class Program
{
public static void Main(string[] args)
{
Something o = new Something { ID = 10, Value = 10 };
o.If(x =&gt; x.ID == 10, new MyAction(&quot;ID10&quot;)).If(x =&gt; x.Value
&lt; 20, new MyAction(&quot;Value20&quot;)).DoSomethingWithMyAction();
SomethingElse o2 = new SomethingElse { S = &quot;ABC&quot; };
o2.If(x =&gt; x.S == &quot;A&quot;, new
MyAction(&quot;AA&quot;)).DoSomethingWithMyAction();
Console.ReadKey();
}
}
}
I was trying your approach and it does what I am looking for.

But I would like to not use Tupples. Instead something like:

MyClass<T, MyAction> ...

Which is seems similar to Peter's solution ...

But I am having problems with it as I just posted.

You posted some code with an A class.

But as far as I can see it is a Tuple.

I can not see the difference.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top