-2

I have a piece of code similar to this

public string GetMessage()
{
    if (new Random().Next(10) % 2 == 0 == 0)
    {
        string message = "bad luck";
        return message;
    }

    string message = "lucky";
    return message;
}

This code could surely be improved, but what's puzzling me is that it unexpectedly produces the error

A local or parameter named 'message' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Now what's weird about this is that the variable in the smaller scope shouldn't even exist to cause the clash. It's legal in C:

char* GetMessage()
{
    if (rand() % 2 == 0)
    {
        char* message = "bad luck";
        return message;
    }

    char* message = "lucky";
    return message;
}

This compiles and works. As soon as the smaller scope ends, the variable inside of it ceases to exist and I'm free to reuse the name. Similar code also works in Swift, so why is this different in C#?

Martin
  • 17
  • 2
  • Does this answer your question? [Variable scope confusion in C#](https://stackoverflow.com/questions/1196941/variable-scope-confusion-in-c-sharp) – zdimension Aug 02 '20 at 16:34
  • 2
    Why do you expect C# to adopt or share the scoping and variable naming rules of other languages? C# is not C, nor is it Swift, so why should they influence or be relevant to a C# error? Also, the double `== 0 == 0` won't compile. – Lance U. Matthews Aug 02 '20 at 16:59
  • what happens when you use an else statement? – RadioSpace Aug 02 '20 at 18:24

2 Answers2

0

In C#, any variables declared in a block will remain in scope throughout the entire block where they have been declared. This means that if you declare a variable in an if/else block, you cannot then declare a variable with the same name below in the same method block, as C# will see it already exists.

This site explains variable scope in C# really well in my opinion if you would like to check it out.

Rhys Wootton
  • 182
  • 8
  • You are partially right. It has to do with scoping, but it's the other way around. A variable defined in a block is visible in this block and all enclosed scopes, but not vice versa. Thus, the `message` in the body of the `if` block is not visible in the method's scope, but the `message` in the method's body is visible in the `if` block (even though it's defined a few lines below, but that doesn't matter in C#). Thus the error is pointing to the `message` variable inside the `if` and not to the `message` variable in the method's body. – derpirscher Aug 02 '20 at 17:05
  • Ah okay, that makes sense. Thanks for correcting me! – Rhys Wootton Aug 02 '20 at 17:35
0

You had rather good luck with your c sample. In c we expect that the storage for "message" is out of scope after return : but the pointer returned points to where the value of "message" used to be. To correct the c, declare and define a local variable with enough space to take the longest message IN THE CALLING FUNCTION. Pass a pointer to that space to the function, rather than returning a dangling pointer. As a side note: in production code, your c code might work for years then unexpectedly show intermittent failures. Please review the scope rules in both c and c#.

sys101
  • 19
  • 3