-2

What is an elegant (easy to extend as there might be more functions than just A and B) way to implement the following pseudocode?

1. Execute A()
2. Execute B()
3. If A or B succeeded, then do C()

The simple code

if (A() || B())
    C();

won't work because in this case, if A() succeeds, B() isn't executed.

Dunno
  • 3,632
  • 3
  • 28
  • 43
  • 4
    Assign the return to a var and check them. – Trevor Jun 24 '19 at 15:52
  • @Çöđěxěŕ that's not really elegant, becuase if I have more functions I'll have to add more vars and the whole thing will bloat unnecessarily. The `|` operator looks like a better option – Dunno Jun 24 '19 at 15:56
  • Yeah, you can't use an expressions like that in your situation, because conditional logical operators in C#/.NET are ["short-circuiting"](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-or-operator-) –  Jun 24 '19 at 15:56
  • 1
    _bool ok = A(); ok |= B(); if(ok) C();_ – Steve Jun 24 '19 at 15:59

3 Answers3

5

Just use logical or operator:

(Use one | instead of ||)

using System;

public class Program
{
    public static bool A(){
        Console.WriteLine("A");
        return true;
    }
    public static bool B(){
        Console.WriteLine("B");
        return true;
    }
    public static void Main()
    {
        if(A() | B())
        Console.WriteLine("Hello World");
    }
}

// Output:
// A
// B
// Hello World

You can run with .NET Fiddle.

baruchiro
  • 5,088
  • 5
  • 44
  • 66
2

Use “or” that is not short circuited- | (MSDN:Operator or).

The | operator evaluates both operands even if the first operand evaluates to true, so that the result must be true regardless of the value of the second operand.

While using this | operator does exactly what requested in the question it may not be good idea to write in code that needs to be maintained. The | is commonly used as "bitwise or" and most people don't know that in C# it is also defined for Boolean values as "non short-circuiting or". If you decide to use it the code consider adding comment and ideally add unit test that verifies the behavior needed.

For regular code I'd capture results of all methods first and than see if there are any true values.

var results = new[] { M1(), M2(), M3(), M4() };
if (results.Any())
{ … }
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • `if A() succeeds, B() isn't executed.` this will not work given the solution – Trevor Jun 24 '19 at 15:53
  • 7
    @Çöđěxěŕ according to https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#logical-or-operator- using `|` instead of `||` will work – Dunno Jun 24 '19 at 15:54
  • 2
    @Çöđěxěŕ https://ideone.com/ERdiYl – 001 Jun 24 '19 at 15:57
  • 1
    @Çöđěxěŕ || is short-circuited OR (the moment that any passes then it stops evaluating). | is a normal OR, it does EXACTLY what you are asking for. Stop arguing and read the docs. – Steve Todd Jun 24 '19 at 16:01
  • @elgonzo I know what that operator does but how do you execute all functions even if one doesnt succeed? IMHO the OP wasnt neccessarily clear on the question. `Check if any function succeeds, but execute all` doesnt make sense. – Trevor Jun 24 '19 at 16:02
  • 4
    @Çöđěxěŕ Apparently you *don't* know what the operator does. It does it by not checking the result of the first operand before evaluating the second. – Servy Jun 24 '19 at 16:04
  • @Servy I know what it does, what happens when it returns false does the other functions get executed? – Trevor Jun 24 '19 at 16:09
  • 2
    @Çöđěxěŕ You mean what does the other function do? Whatever it was written to do. Given that the OP wants to run it regardless of the success or failure of the first, they are presumably independent of each other and one failing doesn't adversely affect the other. If not, they'll need to be written to function properly if the other one fails, however they want to do that. It's irrelevant to the question of how to call the method though. – Servy Jun 24 '19 at 16:11
  • 1
    @Çöđěxěŕ if you read the docs like we told you "The | operator evaluates both operands even if the first operand evaluates to true, so that the result must be true regardless of the value of the second operand." – Steve Todd Jun 24 '19 at 16:11
  • 2
    @Çöđěxěŕ Yes, all the functions get executed with the logical operators `|` and `&`, regardless of the result of the previous function. The conditional operators `||` and `&&` stop executing as soon as it's clear that no more executions are needed to complete the evaluation. – Rufus L Jun 24 '19 at 16:11
  • 2
    This discussion in the comments confirms my downvote: the answer is not helpful without any links and without any examples. I works, but neither OP nor future readers will learn why. – Thomas Weller Jun 24 '19 at 16:14
  • @ThomasWeller, while i agree that the answer as such is not a good-quality answer, basing the judgement of quality of an answer on a discussion revolving around the opinion of _just_ one individual and which is only tangentially related to the question is ludicrous. Because then there will never be any good answer, because there will always be someone who either doesn't understand something in an answer or just interprets and blind-guesses too much into the question presented. Frankly, the whole discussion here could have happened underneath any answer, irregardless of how good that answer is. –  Jun 24 '19 at 16:21
  • @ThomasWeller - I agree that this is actually very bad answer (updated to reflect that) - only answers the question as asked but did not consider real world consequences. I should not have recommended something most people are not aware of. Additionally I totally agree that it should have been additionally downvoted for not looking for [duplicates](https://stackoverflow.com/questions/3244316/how-to-avoid-short-circuit-evaluation-in-c-sharp-while-doing-the-same-functional) first. Thanks for feedback (unfortunately exactly the same answer is accepted - OP will be in trouble later for it :) ) – Alexei Levenkov Jun 24 '19 at 17:58
-1

Suppose that we have three functions as below:

public static void A() => Console.WriteLine("A");

public static void B() => Console.WriteLine("B");

public static void C() => Console.WriteLine("C");

You can use the following approach:

var task = Task.Run(A)
                .ContinueWith(t => B(), TaskContinuationOptions.NotOnFaulted)
                .ContinueWith(t => C(), TaskContinuationOptions.NotOnFaulted);

task.Wait();

Which will executes the A() and if it executes successfully, then will execute B() and if it succeeded to then C() will be executed. If any exception occurred while executing A() or B(), the children tasks will not be executed.

Thanks to @AlexeiLevenkov, if these methods are doing some CPU intensive works, then paralleling them will give you notable performance benefits, otherwise paralleling might have negative impact on your work!

Microsoft says:

When parallelizing any code, including loops, one important goal is to utilize the processors as much as possible without over parallelizing to the point where the overhead for parallel processing negates any performance benefits

Read more here: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-for-loop#matrix-and-stopwatch-example

Vahid Farahmandian
  • 6,081
  • 7
  • 42
  • 62
  • Creating threads just to replace "or"... sounds like very bad idea. And `.Wait()` at the end not making it any better. – Alexei Levenkov Jun 24 '19 at 18:00
  • @AlexeiLevenkov thanks for the comment, but would you please say why this is very bad idea? – Vahid Farahmandian Jun 24 '19 at 18:57
  • https://stackoverflow.com/questions/2453378/threading-cost-minimum-execution-time-when-threads-would-add-speed, https://stackoverflow.com/questions/15021304/an-async-await-example-that-causes-a-deadlock – Alexei Levenkov Jun 24 '19 at 20:02
  • @AlexeiLevenkov I read that posts, but still I did not find any evidence for your comment! – Vahid Farahmandian Jun 25 '19 at 02:52
  • Feel free to ask new question about it. Or if you want I can ask it for you - I don't see how to explain that better. – Alexei Levenkov Jun 25 '19 at 03:20
  • @AlexeiLevenkov thank you. lets imagine this code: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-for-loop suppose that we have three method which are doing some calculations as described in this link. execution time in sequential mode and parallel mode are really notable. – Vahid Farahmandian Jun 25 '19 at 04:14
  • @AlexeiLevenkov I have updated the answer, would you please gimme your great comments? – Vahid Farahmandian Jun 25 '19 at 04:23