In VB I can write a loop that always executes at least once. For example:
Do
[code]
Loop While [condition]
Is there a way to do that in C#?
Sure:
do
{
...
} while (condition);
See do (C# Reference).
do
{
// code
} while (condition)
Alternatively
bool finished = false ;
while ( !finished )
{
// do something
finished = // evaluate a new foo
}
I've never been a huge fan of do/while
TopOfLoop:
// ...
if (condition)
{
goto TopOfLoop;
}
No career is complete without at least one goto.
Related
I have a couple IF statements and am trying to figure out how to have the first If statement execute something and not the second but if the first is not true then execute the second one.
if (condition)
{
do_something;
}
if(condition_2)
{
do_something_also;
}
I want the first if statement to happen but after it executes I want it to skip the second if statement.
If the first do_something happens I want to skip the second if statement completely.
How do I go about doing this?
Use else if:
if (condition)
{
do_something;
}
else if(condition_2)
{
do_something_also;
}
Just use if - else if...
if(condition){
do_something();
} else if (condition2){
do_something_also();
}
Here is an example of my code. I need the last if to do nothing, else do something.
if (daPilot.Gas > 0)
;
else
daPilot.failMessage3();
You've already done it. Congratulations.
Of course the far less confusing design is to just NOT the condition and then have an if with no else.
if (daPilot.Gas > 0)
{
// nothing
}
else
{
daPilot.failMessage3();
}
Or more simply,
if (daPilot.Gas <= 0)
{
daPilot.failMessage3();
}
Two ways:
Empty curlys:
if (condition)
{
}
else
{
method();
}
Realize that you can simply invert the conditional:
if (!condition)
method();
There is no point of putting a condition for doing nothing. You should do it like this.
if (daPilot.Gas <= 0)
daPilot.failMessage3();
Simply invert the if condition and declare only the true part:
if (daPilot.Gas <= 0)
daPilot.failMessage3();
Anyway, you are always able to declare an empty body when needed: { }.
For instance:
while (condition)
{
}
Reverse the if:
if (daPilot.Gas <= 0) daPilot.failMessage3();
You can invert if, try this:
if (daPilot.Gas <= 0)
{
daPilot.failMessage3();
}
if you really want it to do nothing
{
if (daPilot.Gas > 0)
{
}
else
{
daPilot.failMessage3();
}
}
Let's use the '!' operator like:
if (!(daPilot.Gas > 0))
daPilot.failMessage3();
or with an extra variable:
var isGasGreaterToZero = daPilot.Gas > 0; /*true or false*/
if(!isGasGreaterToZero)
daPilot.failMessage3();
In both cases if daPilot.Gas is greater than zero (0) nothing will happen!
I like the following code - it uses zero or one line but need extend to tree lines
#pragma warning disable CS0642 // Possible mistaken empty statement
;
#pragma warning restore CS0642 // Possible mistaken empty statement
Also use { } in two lines or zero line in if statement:
if (...) { }
Inside the if statement write some code that does nothing:
if (daPilot.Gas > 0) var S = true;
I concur with the other answers here. Better to reverse the condition and if you dont want to do that, better to use the empty block { /* nothing */ }.
But now, suppose you are looking for a solution that:
Does not reverse the condition.
Does not use code blocks.
Does not generate a warning or an error or suppress such message.
Has minimal impact on generated compiler code.
How can you do that?
Answer: use _ = 0.
I came up with the following code example which is valid in .NET 3 and 5:
if (new Random().Next(2) == 0)
_ = 0; // do nothing
else
Console.WriteLine("Do Something");
If you ckeck at the compiler generated IL code without optimization you see the the instruction has been replaced by a nop.
With optimizations, the condition has been reversed by the compiler and the then part of the conditional is completely optimized away.
Conclusion: _ = 0; fits the bill.
So at work i am moving all our old VB code to C# and i encountered a problem.
In the VB Code it is
Do While (iterator.NextCourse(course_list, prof_relation, prof_list, index))
course = course_list(index)
course_title_id = CType(course(CourseListQueries.GetCourseListCols.CourseTitleId), Integer)
course_id = CType(course(CourseListQueries.GetCourseListCols.CourseId), Integer)
prof_name_list = String.Empty
For Each prof As DataRowView In prof_list
If (Not IsDBNull(prof(CourseListQueries.GetCourseProfsCols.ProfId))) Then
last_name = CType(prof(CourseListQueries.GetCourseProfsCols.LastName), String)
first_name = CType(prof(CourseListQueries.GetCourseProfsCols.FirstName), String)
If (IsDBNull(prof(CourseListQueries.GetCourseProfsCols.PreferredName))) Then
preferred_name = first_name
Else
preferred_name = CType(prof(CourseListQueries.GetCourseProfsCols.PreferredName), String)
End If
prof_name = preferred_name.Substring(0, 1) & ". " & last_name
If (prof_name_list <> String.Empty) And (prof_name <> String.Empty) Then
prof_name_list &= " / "
End If
prof_name_list &= prof_name
End If
Next
which works fine it works while the method returns bool, but that method is passed by ref. so it links the relation of 2 DataTables.
in C# that code is like
do
{
code...
foreach (DataRowView prof In prof_list) /* crashes here with null object reference*/
{
code...
}
}while(iterator.NextCourse(course_list, prof_relation,ref prof_list, ref index));
so i just want to know, Because in VB the do-while is physically on one line does it run in a different order than the c# method?
How would i go about mending this situation because c# runs top to bottom and only once it's done an iteration does it enter the while method and set those references.
The difference between Do ... Loop While and Do While ... Loop is when the condition is checked.
In the first syntax (equivalent to do { ... } while in C#) the block is executed once, THEN the condition is checked to see if the block should be executed again.
In a Do While ... Loop block (equivalent to while { ... } in C#) the condition is checked first, then the code is executed if the condition is true.
So in your case moving the while to the top of the statement block would make the two fragments equivalent:
while(iterator.NextCourse(course_list, prof_relation,ref prof_list, ref index))
{
code...
foreach (DataRowView prof In prof_list) /* crashes here with null object reference*/
{
code...
}
}
In C# while can also go at the top of the loop, so in your example this would be:
while (iterator.NextCourse(course_list, prof_relation,ref prof_list, ref index))
{
// code...
foreach (DataRowView prof In prof_list) /* crashes here with null object reference*/
{
// code...
}
}
Yes, the VB code runs in a different order than the C# code in your question. The test is happening at the beginning of the loop in your VB code and at the end of the loop in the C# version.
If you change your C# version to a while loop instead of a do while (as in #Richard Ev's answer), they will do the same thing.
you could also try an infinite for loop with a if else break
for(;;)
{
if (iterator.NextCourse(course_list, prof_relation,ref prof_list, ref index))
{
code....
}
else
break;
}
Python's for and while loops include an optional else clause which execute if the loop exits normally (i.e. without a break statement). For example, in Python you could code:
for x in range(3):
print(x)
else
print("The loop exited normally")
And the output will be:
0
1
2
The loop exited normally
How would you accomplish something similar in C# in order to code something like the following:
for (int i = 0; i < 3; i++)
{
Console.WriteLine(x);
}
else
Console.WriteLine("The loop exited normally");
The Python Construct for foreach-else is like this:
foreach( elem in collection )
{
if( condition(elem) )
break;
}
else
{
doSomething();
}
The else only executes if break is not called during the foreach loop
A C# equivalent might be:
bool found = false;
foreach( elem in collection )
{
if( condition(elem) )
{
found = true;
break;
}
}
if( !found )
{
doSomething();
}
Source: The Visual C# Developer Center
Sure:
Use one of the fancy suggestions by the other posters
Use a method that performs the loop, instead of break, you can return to avoid executing code below the loop
Use a boolean variable you can set before you break, and test that after the loop
Use goto instead of break
It's a weird pattern though if you ask me. "Foreach" is always started so the word "else" does not make sense there.
If you're referring to the for-else and while-else constructs in Python, there is a basic IEnumerable<T> extension method that simulates a foreach-else described in this article, with the following implementation:
public static void ForEachElse<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> action, Action #else)
{
foreach (var i in source)
{
if (!action(i))
{
return;
}
}
#else();
}
Googling it gave me that : http://www-jo.se/f.pfleger/.net-for-else
public static void ForEachElse<TSource>(
this IEnumerable<TSource> source,
Func<TSource>,
bool action,
Action #else
) // end of parameters
{
foreach (var i in source)
{
if (!action(i))
{
return;
}
}
#else();
}
I'd like to know if it is possible to get the return value of a function inside a finally block.
I have some code that is like this.
try
{
return 1;
}
finally
{
//Get the value 1
}
I know it's possible by adding a variable that can hold the returned value. But I was wondering if it was possible to get the value in any way.
Thanks
No, you can't do that.
int value = -1;
try
{
value = 1;
}
finally
{
// Now the value is available
}
return value;
If you want to use the variable approach and return early, you could do something like this:
int Method()
{
int #return = -1;
try
{
#return = -2;
return #return;
}
finally
{
// do something with #return
}
}
As others already mentioned, you have to use a variable in this case. However, you can wrap this behavioral pattern into a reusable method using C# 3.0 lambda functions:
static T TryFinally<T>(Func<T> body, Action<T> finallyHandler) {
T result = default(T);
try {
result = body();
} finally {
finallyHandler(result);
}
return result;
}
The TryFinally method allows you to write what you originally needed without repeating the pattern:
TryFinally(() => {
// body of the method
return 1;
}, result => {
// do whatever you need with 'result' here
});
VB.Net allows you to do this:
Public Function GetValue() As Integer
Try
GetValue = 2
Catch
'Something happens
Finally
'Do something with GetValue
End Try
End Function
Which tells you a little bit about what the JIT compiler is going to do.
I think the actual question is - can I systematically trace the exit (and entry?) of various functions - presumably for tracing / troubleshooting etc. How about aspect.net. This lets you insert code dynamically into things