Why c# compiler generates a compile error? [duplicate] - c#

This question already has answers here:
Why can't a duplicate variable name be declared in a nested local scope?
(9 answers)
Closed 9 years ago.
I have following code
using(some code)
{
var b = ....
}
var b = ...
Erorr: A local variable named 'b' cannot be declared in this scope because it would give a different meaning to 'b', which is already used in a 'child' scope to denote something else
Ok, editing
using(some code)
{
var b = ....
}
b = ...
Error: The name 'b' does not exist in the current context

"The local variable declaration space of a block includes any nested blocks. Thus, within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block." Variable Scopes, MSDN

can you do this?
for (int i = 0; i < 10; i++)
{
int j = 1;
}
int j = 2;
The answer is NO which means it pretty much consistent everywhere. Now it begs the question why. Answer to this question is It is illegal to have two local variables of the same name in the same local variable declaration space or nested local variable declaration spaces. And in the above case declaration of J is within the same nested scope.

The correct code should be:
var b = something;
using(some code)
{
b = smth;
}
b = smth;
You cannot use a variable declared inside a block ({}) outside of that block.

Related

Declare Var in If Statement [duplicate]

This question already has answers here:
C# The name ' ... ' doesn't exist in the current context
(2 answers)
The name 'input' does not exist in the current context
(4 answers)
The name does not exist in the current context when using an if statement [duplicate]
(1 answer)
Variable does not exist in the current context?
(6 answers)
the name door does not exist in the current context
(4 answers)
Closed 1 year ago.
yes i know there is a bunch of other threads with likely the same question... but i still dont get it.
I'm writing in C# via Visual Studio and want to make something like an menu so you can choose different options... dependind on which option you choose, the variable will change.
But it's important to have only one variable, so the variable will change when the user is chooses an option.
Something like this:
stt:
string m = Console.ReadLine();
Console.Clear();
int c = Convert.ToInt32(m);
if (c == 1)
{
var ttt = "one";
}
if (c == 2)
{
var ttt = "two";
}
else {
goto stt;
}
Console.WriteLine("" + ttt);
Console.ReadKey();
I always get the error
The name 'ttt' does not exist in the current context
So I have to declare the var outside the if statement... but how??
By writing..
string ttt;
..above the first if. You can't write var ttt; above the if, because it doesn't declare the type (and you're not providing a value so the compiler cannot infer the type), so you have to give the type (string) when you declare the name
If you do this you'll have to remove the vars inside the ifs (but leave eg ttt = "one") so you don't end up declaring another variable with the same name
The quick of it is:
stt:
string m = Console.ReadLine();
string ttt;
Console.Clear();
int c = Convert.ToInt32(m);
if (c == 1)
{
ttt = "one";
}
if (c == 2)
{
ttt = "two";
}
else
{
goto stt;
}
Console.WriteLine("" + ttt);
Console.ReadKey();
Why? Concept called variable scopes. In your sample, ttt was only created inside the if statement, or the else statement, and therefore would not live beyond the scope of that statement. In order to address ttt outside of those limited scopes, it had to be declared higher up.
Off topic - goto. Please try to use loops or conditionals.

C# Referencing the value of a variable [duplicate]

This question already has an answer here:
Is it possible to instantiate objects with variable names, or access variable names at runtime?
(1 answer)
Closed 1 year ago.
I'm having difficulty understanding how I can reference the return value of a variable to create another in C#.
string name = Console.ReadLine();
List<Thing> name = new List<Thing>();
For example, user inputs "Cats" and thus a new list Cats is created.
Or in this scenario:
for (int i = 0; i < 5; i++)
{
List<Thing> (animal + i) = new List<Thing>();
}
Where the lists created becomes animal0, animal1, animal2... etc.
Thank you
You cannot do that in C# at least not naturally.
Variable are determined at the compile time.
Value you are talking about (Cats, animal0, ...) are determined at the runtime, when the code is really running, which occurs after the compilation. So those values cannot become variable names.
You cannot create variables dynamically at runtime, so every variable you would like to use needs to be declared on compile time. Nevertheless, a List<Thing> can hold multiple instances of a Thing at the same time, representing - in your sense - multiple variables.
For example:
var things = new List<Thing>();
for (int i = 0; i < 5; i++) {
things.Add(new Cat()); // if Cat derives from Thing
}
// access the list items by index
Console.WriteLine(thing[0]);
Console.WriteLine(thing[1]);
...

Access the value of a variable outside its scope [duplicate]

This question already has answers here:
Access variable inside while loop from outside (C#)?
(4 answers)
Closed 2 years ago.
I am new to C# and trying to automate a window app using appium .I have the following code
int i = -1;
foreach (var row in SummaryTableRows)
{
i++;
//Console.WriteLine(row.Text);
if ((row.Text.Contains("cheq")) && (row.Text.Contains("acitve")))
{
var DemandData = FirstRow.Split(new[] { " " },
StringSplitOptions.RemoveEmptyEntries);
string Sub = DemandData[1];
string Type = DemandData[0];
bFlag = true;
break;
}
}
buttonBar.ExitFormBtn.Click();
buttonBar = null;
//Should be back to member form
SubCheq.SendKeys(Sub + Keys.Tab);
I want to access the value of Sub and Type outside the if loop. In vb script it was never an issue but seems like in C# the scope of the variable is limited to the foreach block. So My question how can I access the value of Sub and Type.
You can not access a variable outside of it's scope. The scope literally means "where you can access the variable". So you want to accesss the values, where you can not access the values. At wich point you can access the variable there, and that is it's new scope.
What you can do is change the scope. If you want a variable avalible outside a specific block, declare it outside of that block. Just declare sub (and propably type) outside the loop. Then only set the values insdie it, with every loop.
I am unsure why you even ask, as you already do that with i: int i = -1; is a declaration with initialisation. And i++; is jsut shorthad for i=i+1;, so you re-assing it every loop (the new value just happens to be close to the ol one). Strings you many want to initialize with null or maybe a empty string, depending on what you do with it later/how you check for 0 itterations of the foreach loop.

On Scope of Variables in .NET(c#) [duplicate]

This question already has answers here:
Variable scope confusion in C#
(4 answers)
Closed 9 years ago.
Reference Code
public void MyMethod()
{
string x;
List sampleList = populateList();
foreach(MyType myType in sampleList)
{
string x; // why is this not allowed?
doSomethingwithX(x);
}
}
I recently started learning C# and today ran into issue with code similar to the above. VS2010 flagged the commented code with this message a local variable named x cannot be declared in this scope because it would give a different meaning to variable x which is already used in parent or current scope to denote something else....
I dont get it...isnt that the whole essence of block statements and scoping...I know i can just change my variable names and go ahead.but i'd like to know WHY?
I dont get it...isnt that the whole essence of block statements and scoping...
No, not really. The intention of scoping isn't "to allow you to reuse names".
I know i can just change my variable names and go ahead.but i'd like to know WHY?
It reduces the possibilities for confusing code, basically. There are various situations where C# prevents you from writing code which is confusing. Not as many as we might like, of course, but where there's no clear benefit from allowing something, and a clear benefit from disallowing it, it makes sense to disallow it.
Would you ever want to work with code that had the same local variable name in scope twice? Wouldn't you always prefer the original developer to use a different name? I would - so I'm glad the compiler enforces that.
Note that this doesn't prevent the same local variable name being used twice in the same method - they just can't be in the same scope. So this is valid:
public void Foo()
{
{
int x = 10;
...
}
{
int x = 10;
...
}
}
But this isn't:
public void Foo()
{
{
int x = 10;
...
}
int x = 10;
...
}
If the second example is confusing, you need to bear in mind that the scope of a local variable is the block in which it was declared - not from the declaration point onwards.
Previously defined x is still in scope that's why compiler stops you from declaring other one.
You can verify this by limiting the scope of previous variable by wrapping it in curly braces -
public void MyMethod()
{
{
string x;
}
List sampleList = populateList();
foreach(MyType myType in sampleList)
{
string x; // This will be fine.
doSomethingwithX(x);
}
}
The x in the for loop is not visible outwith the loop, but the x you declared at the start of the method is visible within the for loop.
Outwith the loop you have one x but inside it there are two, both of which are being declared
You cannot declare string x; again. .. it will have different meaning. Since string x; is declared inside a method. The scope of x will be available through out the method. . So please declare some other variable inside for each loop. ..
Or you can just x. Instead of declaring again. .

What is the scope of the counter variable in a for loop?

I get the following error in Visual Studio 2008:
Error 1 A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
This is my code:
for (int i = 0; i < 3; i++)
{
string str = "";
}
int i = 0; // scope error
string str = ""; // no scope error
I understand that str ceases to exist once the loop terminates, but I also thought that the scope of i was confined to the for loop as well.
So i has the same scope as a variable declared just outside of the for loop?
Edit:
Just to be clear, I am using C#. I am debating removing the "C" tag. However, since the correct answer explains the difference between the two, I figure it makes sense to leave both tags.
I had an error in my code comment above:
for (int i = 0; i < 3; i++)
{
string str = "";
}
int i = 0; // scope error
string str = ""; // also scope error,
// because it's equivalent to declaring
// string str =""; before the for loop (see below)
I think you're all confusing C++ and C#.
In C++, it used to be that the scope of a variable declared in a for expression was external to the block that followed it. This was changed, some time ago, so that the scope of a variable declared in a for expression was internal to the block that followed it. C# follows this later approach. But neither has anything to do with this.
What's going on here is that C# doesn't allow one scope to hide a variable with the same name in an outer scope.
So, in C++, this used to be illegal. Now it's legal.
for (int i; ; )
{
}
for (int i; ; )
{
}
And the same thing is legal in C#. There are three scopes, the outer in which 'i' is not defined, and two child scopes each of which declares its own 'i'.
But what you are doing is this:
int i;
for (int i; ; )
{
}
Here, there are two scopes. An outer which declares an 'i', and an inner which also declares an 'i'. This is legal in C++ - the outer 'i' is hidden - but it's illegal in C#, regardless of whether the inner scope is a for loop, a while loop, or whatever.
Try this:
int i;
while (true)
{
int i;
}
It's the same problem. C# does not allow variables with the same name in nested scopes.
The incrementor does not exist after the for loop.
for (int i = 0; i < 10; i++) { }
int b = i; // this complains i doesn't exist
int i = 0; // this complains i would change a child scope version because the for's {} is a child scope of current scope
The reason you can't redeclare i after the for loop is because in the IL it would actually declare it before the for loop, because declarations occur at the top of the scope.
Yea. Syntactically: The new scope is inside the block defined by the curly strings. Functionally: There are cases in which you may want to check the final value of the loop variable (for example, if you break).
Just some background information: The sequence doesn't come into it. There's just the idea of scopes - the method scope and then the for loop's scope. As such 'once the loop terminates' isn't accurate.
You're posting therefore reads the same as this:
int i = 0; // scope error
string str = ""; // no scope error
for (int i = 0; i < 3; i++)
{
string str = "";
}
I find that thinking about it like this makes the answers 'fit' in my mental model better..

Categories