When are curley braces required around single statements? - c#

In my answer here: C# Lock syntax - 2 questions, LukeH pointed out that try...catch...(finally) statements require curly braces.
I found the answers as to why, found here ( Why do try..catch blocks require braces? ) very interesting.
I'd like to know of any more examples where curly braces are required as opposed to good practice etc, ideally with code snippet and explanation as to why.

Around a method body.
// not allowed:
int Inc(int x)
return x+1;
The why is not so easy, it would seem old-style C needed it more than C++/C#.
A little more about the why part, in (very) old C you would write
int Sum()
int a, b; // parameters, very informal
{
int s; // local var
...
}
So this ancient syntax needed the braces. And in all the languages that are based on C, nobody ever saw a point in making them optional, assuming that was possible in some cases.

Certain parts of language require braces to be present. For example, when you start a method you have to open and close braces to identify that as a code block. Inside a function certain language features like loops, conditinal statements, etc. also accept braces although in some cases they are not required. For example:
if (someValue == true)
doSomething();
In this case braces are not required, however you can surround this statement with braces, because you have just one statement that will be executed after if check, but if you want to execute multiple statement inside an if you need to use braces. For example,
if (someValue == true)
{
doSomething();
doSomeMoreWork();
}
Trying something like this is not allowed:
if (someValue == true)
doSomething();
doSomeMore();
else
doWork2();
int i = 1 + 2;
Compiler will complain in this case.
The problem can best be seen in the following loop:
while(i < 10)
doSomeWork();
i++;
Here you would expect i to increment, but this never happens. Basically this loop is the same as this one:
while(i < 10)
{
doSomeWork();
}
i++;
The statement inside the block will execute infinetly and i will never increment. In that case the proper way to write this statement would be:
while(i < 10)
{
doSomeWork();
i++;
}
Now you have a properly working statement. I like to use braces all the time regardless of number of statements that are being executed. The reason for this is that sooner or later I might need to add some more work in my if statement or inside a for or foreach loops. It's just a good practice.

You must use either braces or parentheses with checked and unchecked, depending on whether you're treating them as operators or statements:
// legal operator
int y = checked(x * 2);
// legal statement
unchecked
{
if ((a * b) > c)
{
DoSomething();
}
}
// illegal operator
int y = checked x * 2;
// illegal statement
unchecked
if ((a * b) > c)
DoSomething();

class/struct/interface declaration
class X { int _myval }

Related

How can I replace an if statement with a ternary operator?

I am trying to replace the conventional if statement with ternary operator, but it does not compile.
First I would like to check if the input is a number, if true then assign Student.ID to input, if falsethen tell a user to try again.
My code:
(Int32.TryParse(Console.ReadLine().Trim().ToLower())) ? student.ID : Console.WriteLine("id isn't a number, try again");
What am I missing?
As I read it, you want to output something if the parsing fails. This can not be turned into a ternary.
There is a lot of things that are wrong with your code:
Tenaries are only for conditional assignments. You do not have a variable you assign anything to.
you never gave TryParse the out parameter, meaning the Compiler can not figure out wich function to even call there
Both options of a ternary must fit type you are doing assignment too. Console.WriteLine returns void, wich is propably not the same type you will have for Stundent.ID (I asume a integer).
So there are at least 3 reasons this can not compile.
Just keep it at the working if/else block. If you want to try ternaries, do stuff like applying a upper/lower bound for a value. That is what it is designed for. Rarely you use it for initialisation work (if == null, make a new instance. Otherwise give the value).
Edit: I just re-read and noticed that a assignment is not mandatory. It is just the very, very common usecase. And in that case, both results (or their return value) must fit the variable.
Christopher answered the question pretty well, so I won't repeat it here.
A workaround for what you're trying to do may be to implement a method that prompts the user for some input and doesn't return until the user enters a string that can be converted to the expected type (and optionally meets some other conditions).
For example:
private static int GetIntFromUser(string prompt, Func<int, bool> validator = null)
{
int result;
var cursorTop = Console.CursorTop;
do
{
ClearSpecificLineAndWrite(cursorTop, prompt);
} while (!int.TryParse(Console.ReadLine(), out result) ||
!(validator?.Invoke(result) ?? true));
return result;
}
private static void ClearSpecificLineAndWrite(int cursorTop, string message)
{
Console.SetCursorPosition(0, cursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, cursorTop);
Console.Write(message);
}
Now we can call this method in our main program and not worry about validation - our main code is much cleaner.
For example, say a student number must be 5 digits long, we could do something like:
int studentId = GetIntFromUser("Enter a 5-digit student id: ", x => x > 9999 && x < 100000);

C# goto user input

I am making an OS with Cosmos and want to use goto to go to the user input but I am getting the error
No such label 'input' within the scope of the goto statement
'input' is a variable in which the user has inputted.
I can understand why this is happening but how do I fix it?
You cannot user variables as scope identifier for goto statement.. you have to use label identifier within scope (namespace) indicating it by ":" ..
for example
using System;
class Program
{
static void Main()
{
Console.WriteLine(M());
}
static int M()
{
int dummy = 0;
for (int a = 0; a < 10; a++)
{
for (int y = 0; y < 10; y++) // Run until condition.
{
for (int x = 0; x < 10; x++) // Run until condition.
{
if (x == 5 &&
y == 5)
{
goto Outer;
}
}
dummy++;
}
Outer:
continue;
}
return dummy;
}
}
method M contains three nested loops. The first loop iterates through numbers [0, 9], as do the two inner loops. But in the third loop, a condition is checked that causes the loop to exit using the break keyword.
For
Break
The code increments the dummy variable after each completion of the inner loop. If the inner loop is exited early, this variable should be left alone. With the goto statement, it is not incremented.
Result:
The value 50 is printed to the console. The int is incremented 10 x 5 times.
However:
If the goto was a break, the result would be 10 x 10 times, or a total of 100.
Hope this Help.. :)
I am making an OS with Cosmos
For getting any remotely useful answers, I think you will have to give some information about the scope of the OS. Are you only fiddling around with COSMOS a bit, or do you have some special use-case you want to serve with a custom COSMOS OS?
and want to use goto to go to the user input
Especially in the latter case (specialized OS) you should clearly refrain from using GOTO, unless you have a very good reason to do so (and in my humble opinion there is no such thing as a really good reason to use GOTO). There are viable alternatives to GOTOs in modern programming languages and you should re-think your design, algorithm, whatsoever.
To answer your question. Here is an example that produces the very error message you are experiencing
private void FirstMethod()
{
goto MyLabel;
}
private void SecondMethod()
{
MyLabel:
return;
}
I have defined a label in Method. Anyway, from Main you cannot simply jump from main to another method, since the compiler would not know where to return to, after the method has finished, since no data would have been pushed to the call stack on GOTO (please see the Wikipedia page about the call stack for further information).
The following, anyway, would work, since the label and the GOTO live within the same scope
void MyMethod()
{
goto MyLabel;
// do something
MyLabel:
return;
}

a ; without statement in C#

I was looking at a code sample in C#. There is ; without any statement before it. I thought it is typo. I tried to compile with ;. It compiled fine. What is the use of ; without any code statement?
I'm using VS 2010, C# and .Net 4.0
private void CheckSmcOverride(PatLiverSmc smc)
{
;
if (smc.SmcOverride && smc.Smc != null
&& smc.Smc.Value < LiverSmcConst.SMC_OVERRIDE_POINT)
{
smc.Smc = 10;
_logger.DebugFormat("CheckSmcOverride: Override SMC {0}", smc.Smc);
}
}
A semicolon in C# is simply to denote an end-of-a-statement. Empty statements, or just a ; by itself, are valid.
You could have the following on a line by itself inside any function in C# and it should will compile fine:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
On the same topic, but semi-different from the question at hand, is an empty set of curly-brackets, { }. These denote a "code block", but are valid just about anywhere in your code. Again, you could have something like the following on a single line and it will still compile fine:
{ } { ;;;;;;;;;; } { }
In the end, the empty-statement and empty-code blocks all compile down to "nothing to see here folks, move along" and can, in most cases, be removed from the code without consequence.
As a c# developer I use the 'empty statement'
;
(a useful case as a comment requested)
when I have a multi line lambda and I want to examine the last line of evaluation i.e.
list.ForEach(x=>
{
x.result = x.Value * x.AnotherValue;
; // otherwise I can't ever see these as you can't break on the end brace of an anonymous function
})
as a way to break point inside some code after evaluation of the line before i.e.
void SomeFunct()
{
int a = someOtherFunct();
; //I want a breakpoint here but...
//there is some huge code segment that will get skipped before I can breakpoint
}
It's a statement that does nothing. Normally this would be pointless and could just be removed, but there are times where a statement is expected and you really want nothing to happen.
Sometimes you see this with loops that cause side effects and so need no body:
int count = 0;
while(isTheRightNumber(count++))
;
Personally I dislike such code examples and discourage the practice as they tend to be harder to understand than loops that have side effect free conditions. Using a set of empty braces is a bit clearer, as is including a relevant comment, such as:
int count = 0;
while(isTheRightNumber(count++))
{ } //empty by design
Another example is the pattern of using a for loop for an infinite loop:
for(;;)
{
//stuff
}
is essentially the same as:
while(true)
{
//stuff
}
It's an empty statement. I never used it, but it exists in many languages.
semicolon(;) indicated the end of a statement. so if you just add a semicolon without anything... it means it is empty statment
An empty statement is sometimes used when a statement expects a block but you don't want it to do anything.
For example:
for(i=0; array[i]!=null; i++)
;
or for nested if then elses without braces:
// don't really do this kids
if(cond1)
if(cond2)
doit();
else
;
else
dont();
Sometimes used for 'if' clarity:
if(somecomplicatedconditionisnotfalseinverted()) // <-- this is already complicated enough, let's not ! that.
; // do nothing
else {
ohnoes();
}
But in your example, it does absolutely nothing when built for release and just adds a nop when built for debug, so you can drop a breakpoint on it.

while() without {}?

I had this code in a project in VS2010 - it was a placeholder method I hadn't fully implemented yet. I started the implementation today. Notice there are no {} surrounding the if/else for the while statement. This compiled many times - it has been that way for quite some time. Is this a bug in VS? I thought loops all needed {}
private void ParsefCIPProfiles(string block)
{
StringReader reader = new StringReader(block);
string readline = reader.readline();
while (readline != null)
if ()
{}
else
{}
}
No, it isn't a bug. In fact for single-statement contents, most other scoped statements also don't require the curly braces. For instance:
//This is valid
using (var f = new foo)
f.Bar();
// So is this
foreach (var i in someInts)
Console.Out.WriteLine(i);
Only if there is more than one statement and you want all of those statements to be part of the loop.
Here there is only one if...else statement and that is part of the loop. Anything after that will not be part of the loop and if you want more statements, enclose them in {..}
This is the case with for, if, etc.
See the C# formal grammar: http://msdn.microsoft.com/en-us/library/aa664812(v=vs.71).aspx
while-statement:
while ( boolean-expression ) embedded-statement
embedded-statement:
block
empty-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
checked-statement
unchecked-statement
lock-statement
using-statement
selection-statement:
if-statement
switch-statement
if-statement:
if ( boolean-expression ) embedded-statement
if ( boolean-expression ) embedded-statement else embedded-statement
The important thing to note is that a while-statement requires an embedded-statement, and an if-statement is a selection-statement which is an embedded-statement.
You can derive your sample code with these productions.
You can omit braces when there is just one statement contained in the loop. Or in an if/else statement.
Curly braces aren't usually necessary if there is only one statement following, for example:
if(readline != 0)
doSomething();
Should work because the function doSomething() is in the if loop's scope. However, what I would expect this code to look like if there WERE curly braces (to identify scope boundaries):
while (readline != null) {
if ()
{ }
}
else
{}
NOW the else is not in the scope of the while loop, and I don't see a reason why it wouldn't compile. It just might not behave as you imagine it should.
However, the above code is not quite correct. It does not perfectly mimic your code. If-else statements are considered one statement. Therefore, the scope boundaries are actually looking like:
while (readline != null) {
if ()
{ }
else
{}
}
Edit: Scope is the context in which an identifier can be used. So, the scope of a variable depends on how it is defined and where. That means the variable can only be used in certain places. The scope of a loop is everything within its curly braces; if it doesn't have curly braces, then only the next statement is within the loop's scope.
This code will work:
while(readline != null)
if(readline == 1)
doSomething();
That code works because doSomething() is in the scope of the if statement which is also in the scope of the while loop.
As many of the other posters here have pointed out, the braces are not necessary because the while loop contains only one statement. The if-else is considered to be a single statement even though it is split between multiple lines.
However, I always include braces around all nested statements for the following reason. Consider I have the following code:
while (readline != null)
if (foo = true)
{ DoSomething(); }
else
{ DoSomethingElse(); }
Then later I decide I want to add another statement to my while loop:
while (readline != null)
if (foo = true)
{ DoSomething(); }
else
{ DoSomethingElse(); }
DoYetAnotherThing();
Oops, see my mistake? The DoYetAnotherThing() call will be executed after the loop completes, which is not what I want, because I did not include the braces. If I had included them from the beginning, I would not have had this problem. So I think it is generally a good practice to always include them even when there is only a single statement, it helps avoid errors.
There's also confusion that can be caused by the dangling else problem when you don't use braces, but I'll stop rambling and let you do your own research into that.
There is nothing, syntactically, wrong with the following statement:
while (readline != null)
if ()
{ }
else
{ }
The if ... else is a single statement and will continue until readline is null.
while() without { } will execute the next single statement. if else constitutes a single statement so it will be executed until readline is null.

Multiple variables in switch statement in c

How to write following statement in c using switch statement in c
int i = 10;
int j = 20;
if (i == 10 && j == 20)
{
Mymethod();
}
else if (i == 100 && j == 200)
{
Yourmethod();
}
else if (i == 1000 || j == 2000) // OR
{
Anymethod();
}
EDIT:
I have changed the last case from 'and' to 'or' later. So I appologise from people who answered my question before this edit.
This scenario is for example, I just wanted to know that is it possible or not. I have google this and found it is not possible but I trust gurus on stackoverflow more.
Thanks
You're pressing for answers that will unnaturally force this code into a switch - that's not the right approach in C, C++ or C# for the problem you've described. Live with the if statements, as using a switch in this instance leads to less readable code and the possibility that a slip-up will introduce a bug.
There are languages that will evaluate a switch statement syntax similar to a sequence of if statements, but C, C++, and C# aren't among them.
After Jon Skeet's comment that it can be "interesting to try to make it work", I'm going to go against my initial judgment and play along because it's certainly true that one can learn by trying alternatives to see where they work and where they don't work. Hopefully I won't end up muddling things more than I should...
The targets for a switch statement in the languages under consideration need to be constants - they aren't expressions that are evaluated at runtime. However, you can potentially get a behavior similar to what you're looking for if you can map the conditions that you want to have as switch targets to a hash function that will produce a perfect hash the matches up to the conditions. If that can be done, you can call the hash function and switch on the value it produces.
The C# compiler does something similar to this automatically for you when you want to switch on a string value. In C, I've manually done something similar when I want to switch on a string. I place the target strings in a table along with enumerations that are used to identify the strings, and I switch on the enum:
char* cmdString = "copystuff"; // a string with a command identifier,
// maybe obtained from console input
StrLookupValueStruct CmdStringTable[] = {
{ "liststuff", CMD_LIST },
{ "docalcs", CMD_CALC },
{ "copystuff", CMD_COPY },
{ "delete", CMD_DELETE },
{ NULL, CMD_UNKNOWN },
};
int cmdId = strLookupValue( cmdString, CmdStringTable); // transform the string
// into an enum
switch (cmdId) {
case CMD_LIST:
doList();
break;
case CMD_CALC:
doCalc();
break;
case CMD_COPY:
doCopy();
break;
// etc...
}
Instead of having to use a sequence of if statements:
if (strcmp( cmdString, "liststuff") == 0) {
doList();
}
else if (strcmp( cmdString, "docalcs") == 0) {
doCalc();
}
else if (strcmp( cmdString, "copystuff") == 0) {
doCopy();
}
// etc....
As an aside, for the string to function mapping here I personally find the table lookup/switch statement combination to be a bit more readable, but I imagine there are people who might prefer the more direct approach of the if sequence.
The set of expressions you have in your question don't look particularly simple to transform into a hash - your hash function would almost certainly end up being a sequence of if statements - you would have basically just moved the construct somewhere else. Jon Skeet's original answer was essentially to turn your expressions into a hash, but when the or operation got thrown into the mix of one of the tests, the hash function broke down.
In general you can't. What you are doing already is fine, although you might want to add an else clause at the end to catch unexpected inputs.
In your specific example it seems that j is often twice the value of i. If that is a general rule you could try to take advantage of that by doing something like this instead:
if (i * 2 == j) /* Watch out for overflow here if i could be large! */
{
switch (i)
{
case 10:
// ...
break;
case 100:
// ...
break;
// ...
}
}
(Removed original answer: I'd missed the fact that the condition was an "OR" rather than an "AND". EDIT: Ah, because apparently it wasn't to start with.)
You could still theoretically use something like my original code (combining two 32-bit integers into one 64-bit integer and switching on that), although there would be 2^33 case statements covering the last condition. I doubt that any compiler would actually make it through such code :)
But basically, no: use the if/else structure instead.

Categories

Resources