1

I'm creating an anonymous method to generate a radom string.

Before declaring the method, I didn't declare any parameter with the name id. But I couldn't still define string id = string.Empty; inside the method.

// No parameter within name `id` here...

Func<Task<string>> getIdAsync = null;
getIdAsync = async () =>
{
   // string id = string.Empty; // error here. try to use `_id` instead of `id`
   string _id = string.Empty;

   // logic...

   return _id;
};

// _id = ""; // we cann't re-use `_id` here, but `_id` can use `id` below

// `id` is declared after the method
string id = await getIdAsync();

Maybe I misunderstood but I think it should throw me the error when (only in this case):

// declare `id` before
string id = string.Empty;

Func<Task<string>> getIdAsync = null;
getIdAsync = async () =>
{
   /*
    * A local or parameter named 'id' cannot be declared in this scope 
    * because that name is used in an enclosing local scope to define a local or parameter
    */
   string id = string.Empty;

   // logic...       
};

id = await getIdAsync();

Can anyone correct me?

Tân
  • 1
  • 15
  • 56
  • 102
  • What is the error message? – rory.ap Jan 11 '16 at 14:03
  • @roryap I've written the error message inside the second: `A local or parameter name 'id' cannot be declared.....` – Tân Jan 11 '16 at 14:05
  • 3
    You can't do it in both cases for the same reason, whats not clear? You can however use the same `id` variable (not saying that it is good practice) – SimpleVar Jan 11 '16 at 14:06
  • @SimpleVar I think the first case should be valid because I've declare `id` before. – Tân Jan 11 '16 at 14:08

3 Answers3

3

This is correct.

You are trying to redeclare the variable id.

The solution will depend on what you are trying to do. If you want to set id then simply remove the type definition;

getIdAsync = async () =>
{
   id = string.Empty;

   // logic...       
};

However, this isn't good practice as id could get overwitten by code outside your async method - unless you actually want this. If this is just a variable local to the scope of the anonymous method then rename it:

getIdAsync = async () =>
{
   string localId = string.Empty;

   // logic...       
};

It's the same as if you were declaring an object of the same name inside an if statement or loop.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • @SimpleVar's comment said: using `id = string.Empty;` (in your first case) is not a good practice – Tân Jan 11 '16 at 14:20
  • @HappyCoding It isn't - if you can update the variable elsewhere then it could get overwitten. – ChrisF Jan 11 '16 at 14:23
1

The compiler doesn't care what order you declare your local variables with respect to your delegate method because it doesn't know when you're going to use your delegate. So regardless of whether or not you have this statement before or after your delegate declaration, you'll still have a conflict:

string id = await getIdAsync();
rory.ap
  • 34,009
  • 10
  • 83
  • 174
1

It's similar to this question, although that question is dealing with a nested scope rather than an anonymous function, but the reasoning is the same.

The scope of id is the entire function, not just the code after declaration. Since there's no way do disambiguate between the "outer" id variable and the id variable local to the anonymous function, the compiler throws an error to make you specify which variable you are referring to.

D Stanley
  • 149,601
  • 11
  • 178
  • 240