I had to write my own foreach method for various reasons. This resembles an IEnumerable foreach statement:
public void ForEachEdge(in Vertex vertex, Action<Edge> callback)
{
var edge = GetEdge(vertex.BaseEdgeIndex);
do
{
callback.Invoke(edge);
edge = GetEdge(edge.GetNext(vertex.Index));
} while (edge.Index != vertex.BaseEdgeIndex);
}
I'm using it like so but I wish to be able to "break" out of the entire loop:
ForEachEdge(edge.Vertex0Index, (e) =>
{
if (inEdge.AreConnectingSameVertices(e))
{
// break out of inner while loop here ...
}
});
What would be best practice to break?
Return a status value?
Pass a "ref bool stopEnumerating" parameter in? (requires class instance to wrap it in, right?)
Your thoughts ...
I'm mostly concerned about what end users (developers) would expect in such a case.
the ref parameter method won't be as clean as a return value indicating continuation status. You would have to switch to a Func<Edge, bool>
Func<Edge, bool> callback;
...
if (callback.Invoke(edge)) {
/// do your break logic
}
I decided that (for now) I'll go with a Predicate<> rather than Action<>:
public void ForEachEdge(in Vertex vertex, Predicate<Edge> callback)
{
var edge = GetEdge(vertex.BaseEdgeIndex);
do
{
if (callback.Invoke(edge))
break;
edge = GetEdge(edge.GetNextRadialEdgeIndex(vertex.Index));
} while (edge.IsValid && edge.Index != vertex.BaseEdgeIndex);
}
Which makes the user's code look like this:
ForEachEdge(edge.Vertex0Index, e =>
{
if (inEdge.AreConnectingSameVertices(e))
{
// found it, do something, then exit loop
return true;
}
// continue with next item
return false;
});
The nicest thing about this solution: both Predicate<> and Action<> variants can exist side-by-side! User either returns true/false from the predicate, or does not return anything and thus uses the Action<> version, like so:
ForEachEdge(edge.Vertex0Index, e =>
{
if (inEdge.AreConnectingSameVertices(e))
{
// do stuff
}
});
Purrfect! :)
Related
I have a loop inside a C# method that has the following structure.
do
{
getUserInput();
if (inputIsBad)
{
doSomethingElse();
}
} while (inputIsBad);
alternately, with a while loop:
getUserInput();
while (inputIsBad)
{
doSomethingElse();
getUserInput();
}
But both methods use redundant code: the do-while has both an if statement and while loop checking the same condition; the while loop calls getUserInput() both before and inside the loop.
Is there a simple, non-redundant, non-ad hoc way to do what these method patterns do, either generally or in C# specifically, that only involves writing each basic component once?
Assuming that getUserInput(..) can be converted into a expression yielding a boolean value*..
while (getUserInput()
&& isBadInput()) {
doSomethingElse();
}
// Prompts for user input, returns false on a user-abort (^C)
private bool getUserInput() { .. }
Other variations (presumed without non-local state) shown in comments.
*Trivially, it can always be written as a wrapping function - see Local Functions, introduced in C#7. (There are other methods for the same effect, some of which I consider 'too clever'.)
// local function
bool getUserInputAlwaysTrue() {
getUserInput(); // assume void return
return true;
}
while (getUserInputAlwaysTrue()
&& isBadInput()) {
doSomethingElse();
}
This can be followed to pushing out the logic further, in some cases. The general premise holds: getUserInput() is always invoked prior to the next isBadInput().
// local function or member method
// Prompt for user input, returning true on bad input.
bool getCheckedUserInput() {
getUserInput(); // assume void return
return isBadInput();
}
while (getCheckedUserInput()) {
doSomethingElse();
}
do
{
getUserInput();
if (!inputIsBad) break;
doSomethingElse();
} while (true);
I would use a boolean variable, which you need to declare outside the body of the loop. That way you only need to run the inputIsBad check once. I have turned it into a method as well, since that seems more logical.
bool badInput = true; // Assume bad until checked -- failsafe.
do
{
getUserInput();
badInput = inputIsBad();
if (badInput)
{
doSomethingElse();
}
} while (badInput);
Building on user2864740's answer:
Assume getUserInput() can be converted into a function which returns true if the input is good and bad otherwise. Assuming its original return type wasn't boolean or void, return its original return value via an out or ref parameter depending on the case, e.g.
int originalReturnValue;
while (!getUserInput(out originalReturnValue))
{
doSomethingElse();
}
...
bool getUserInput<T>(out T output)
{
// method body
}
I'm looking for a way to pass through items with certain logic. The most obvious answer probably would be to use .Select which is sort of works with most of the cases but I have a special case and the question can be actually rephrased as how to call a certain method after an item is consumed by all subscribers?
I was thinking about an extension looking like this PassThrough(this IObservable<TSource> obj, Action<TSource, IObserver<TResult>> selector) and I would use it in the following way
.PassThrough((source, observer) => {
if(source != null) {
using(var result = new Result(source)) {
observer.OnNext(result);
}
}
});
The most important part of this is calling .Dispose for the result object after the object is passed to OnNext in other words after it is consumed by subscribers. I didn't find such extension method. Could somebody give an example how to achieve it with existing Rx.NET API or how to create an extension which will do this, presuming it is possible?
What you are looking for is probably Observable.Create via an extension method. In your case it may look like the following:
public static IObservable<Result> PassThrough(this IObservable<TSource> obj, T source) {
return Observable.Create(observer => {
if(source != null) {
using(var result = new Result(source)) {
observer.OnNext(result);
observer.OnCompleted();
}
} else {
observer.OnError(Some Error);
...
}
})
}
Obviously depending on whether you want to keep the stream going, you would omit the OnCompleted() call.
See here for more information on usage of Observable.Create:
http://introtorx.com/Content/v1.0.10621.0/04_CreatingObservableSequences.html#CreationOfObservables
I have a Queue that holds a list of delegates that correspond to methods that I want to run in the future. I would like to only have singular instances of any particular method/parameter in queue. In other words, a queue of DoOne(), DoTwo(2), DoThree(3) should be possible where as a queue of DoOne(), DoTwo(2), DoTwo(2) should not be allowed.
I have noticed that _queue.Contains(Func< int >) works through the minimal testing that I have done, but I am worried if I am missing something. Is this a sufficient enough test to determine whether a particular method/parameter is queued, to satisfy what I am trying to accomplish?
Queue<Func<int>> _queue = new Queue<Func<int>>();
void Queue(Func<int> Method)
{
if (!_queue.Contains(Method))
_queue.Enqueue(Method);
}
void QueueOne()
{
Queue( () => DoOne() );
}
void QueueTwo(int val)
{
Queue( () => DoTwo(val) );
}
void DoOne()
{
return 1;
}
void DoTwo(int val)
{
return val;
}
Since each time you call QueueOne or QueueTwo, you create a new function that is passed to the Queue function, I have my doubts that you can find a way to compare those to each other and determine that they match.
This leads me to recommend that you pass an identifier that you will use to make the uniqueness comparison.
In my sample code below, I chose to do this using the CallerMemberName to identify the name of the calling function (i.e. "QueueOne" or "QueueTwo") and refuse to enqueue the item if the queue still had a matching entry.
Queue<Tuple<string, Func<int>>> _queue = new Queue<Tuple<string, Func<int>>>();
void Queue(Func<int> method, [CallerMemberName] string caller = null)
{
if (!_queue.Any(v => v.Item1 == caller))
_queue.Enqueue(Tuple.Create(caller, method));
}
void QueueOne()
{
Queue(() => DoOne());
}
void QueueTwo(int val)
{
Queue(() => DoTwo(val));
}
int DoOne()
{
return 1;
}
int DoTwo(int val)
{
return val;
}
Since you are calling with a parameter they are treated different objects (see Closures in c#)
Change your logicto check the duplication to:
if (!_queue.Where(x => x.Method == Method.Method).Any())
_queue.Enqueue(m);
this will help you to stop adding same method again (even if they have diff parameters)
I want my code to keep trying a method until no exception is thrown, however, unlike this question, I would like it to be written as a generic method capable of running any input delegate/method. Here is what I've had in mind, but I am not sure how to pass the arguments or generic methods through it:
public void tryLoop(Delegate anyMethod, T[] arguments) {
while (true) {
// Could be replaced by timer timeout
try {
anyMethod(arguments);
break;
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
Is this possible?
EDIT: For the academics of it, I would also be curious to know if it's possible to return the result as well.
If you can settle for using closures, you won't need to have to pass parameters to this method all (or have multiple overloads). The result can be returned using a Func.
public T tryLoop<T>(Func<T> anyMethod)
{
while (true)
{
try
{
return anyMethod();
}
catch
{
System.Threading.Thread.Sleep(2000); // *
}
}
return default(T);
}
void SomeMethod(int param)
{
var someLocal = "Hi";
var anotherLocal = 0;
var result = tryLoop(() =>
{
Console.WriteLine(someLocal);
return param + anotherLocal;
});
Console.Write(result);
}
To be honest, I wouldn't set an infinite retry, however - at best, if certain types of retryable error were returned, such as a database deadlock, or a timeout calling an erratic web service, then possibly 3 or 4 retries might be in order. Exceptions such DivideByZero or FileNotFound aren't likely to go away by running them indefinitely :-)
*** especially with deadlocks, sleeping for a random period is recommended, just in case other threads are also simultaneously deadlocking on exactly the same data - you don't want the same deadlock recurrence happening in 2000ms :-).
A way to do this is by using an Action, and remove the arguments parameter:
public void tryLoop(Action anyMethod) {
while ( true ) {
// Could be replaced by timer timeout
try {
anyMethod();
break;
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
This gives you ultimate freedom in how to use it:
tryLoop(() => string.Reverse("abc"));
or like this:
String s1 = "A";
String s2 = "b";
tryLoop(() => string.Concat(s1, s2));
As you can see in the second example, you can directly take the arguments from the context of the tryLoop method being called. You can invoke anything there.
The good thing for this approach is that you will not have to use Invoke or DynamicInvoke as with a Delegate instead of Action, because these introduce a performance penalty.
If you need the result, you can re-write the above with a Func<T> instead of Action, like this:
public T tryLoop<T>(Func<T> anyMethod) {
while ( true ) {
// Could be replaced by timer timeout
try {
return anyMethod();
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
and use it like this:
var reversed = tryLoop(() => string.Reverse("abc"));
String s1 = "A";
String s2 = "b";
var concatenated = tryLoop(() => string.Concat(s1, s2));
Check if this suit your needs. If not then please comment. Also not sure how it will be performance wise.
Also the DynamicInvoke method has an object return type. This you can use to return the result of the delegate. You can change the return type of method from void to object.
public void tryLoop<T>(Delegate anyMethod, T[] arguments)
{
while (true)
{ // Could be replaced by timer timeout
try
{
anyMethod.DynamicInvoke(arguments);
break;
}
catch
{
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
Hope this helps
What is the difference between saying:
if (abc == "a")
{
// do something here...
return;
}
and the same as above, but without the return keyword?
I am a C# coder and I know that the return keyword followed by a type or variable returns that item, but in the above context, return seems to be just to exit the code block but does it make any functional or performance change on the code?
Thanks
"return" exits from the function, not just the enclosing code block. So if your code block was in the context of a function, like so (I don't know C# so I'm using Java syntax):
int thisIsAFunction(int a) {
if (abc == "a")
{
// do something here...
return 1;
}
// do something else here...
}
if abc == "a" then the "do something else here" will not run. But if you removed the return statement inside the if block, then it would run.
return statement exits the function immediately, so it might have performance benefits as the following code in the function would not be executed at all.
MSDN
The return statement terminates execution of the method in which it appears and returns control to the calling method. It can also return an optional value. If the method is a void type, the return statement can be omitted.
Example
//this would do nothing
public void method()
{
return;
}
//this would return true
//notice the return type of bool this means
//the method expects a true\false value
public bool method2()
{
return true;
}
public void test()
{
if(method2())
method()
}
Now if you ran test method2 would always return true and method1 would just end its processing
The return statement does exit the current method, not just the code block (for/while/if/etc). So it is useful for situations like the following:
public void MyMethod(object myObject)
{
if (myObject == null)
{
return; // exits method.
}
// do something with myObject
}
Additional info: I will point out, that many people prefer to have one exit point in a method, however, it can be useful to do something similar to the example here in some cases. I would always try to find ways to limit the number of return or exit points in your method.
In your case, no - but if you had other code after your 'if' statement that you only wanted to run if your statement was false (e.g. if abc != "a"), then the return allows you to bypass that and exit the function / method.
In a loop or case statement, you can use break to achieve this result. This doesn't work on if statements or code blocks in general though.
And yes, return exits the enclosing function.
Executing the return statement will make the execution jump out of the method. Without the return, it would simply go on with the next statement instead.
Yes, your method does not have return type in this case.
e.g.
public void Foo
{
if (abc == "a")
{
// do something here...
return;
}
// some other code
}
This is to say if abd = "a", then exit the method so that some other code won't be executed.
It can be a cleaner way of writing code. I typically do it in a guard clause at or near the beginning of a method. If you have an error condition, just "return" out of the method. It saves wrapping the rest of your work in an else block. Seems trivial, but it helps to reduce code complexity.