6

I assume my question will be totally stupid but I have to know the answer.

Is it possible to initialize a variable just once in this situation?

    static void Main()
    {
        while (true)
        {
            MethodA();
            MethodB();
        }
    }

    private static void MethodA()
    {
        string dots = string.Empty;    // This should be done only once

        if (dots != "...")
            dots += ".";
        else
            dots = string.Empty;

        Console.WriteLine(dots + "\t" + "Method A");
        System.Threading.Thread.Sleep(500);
    }

    private static void MethodB()
    {
        string dots = string.Empty;    // This should be done only once

        if (dots != ".....")
            dots += ". ";
        else
            dots = string.Empty;

        Console.WriteLine(dots + "\t" + "Method B");
        System.Threading.Thread.Sleep(500);
    }

Of course I can initialize string dots out of method but I don't want to do mess in the code, and this can't be done in any other loop too (like for). Any ideas how solve this or am I so stupid to think normally?

Thanks in advance.

EDIT: I've changed the sample code to be more practical. Desired output should be:

.    Method A
.    Method B
..   Method A
..   Method B
...  Method A
...  Method B
     Method A
.... Method B
.    Method A
.....Method B

Etc. etc.

  • You should be using a StringBuilder. – Mike Cole Jul 20 '12 at 16:08
  • 1
    In it's current form, this method will always make `dots = "."` – scottm Jul 20 '12 at 16:09
  • 3
    @MikeC. - in this example, I don't believe using a StringBuilder would be economical. – Inisheer Jul 20 '12 at 16:11
  • 1
    @MikeC. Because it only performs one string concatenation once. it's not in a loop. – Servy Jul 20 '12 at 16:15
  • @MikeC. - Take a look here http://stackoverflow.com/questions/1825781/when-to-use-stringbuilder (specifically the second answer). That answer is worded much better than I could do. – Inisheer Jul 20 '12 at 16:19
  • Since your code makes no sense it is difficult to give you an advice. `dots` is declared as local variable and will always be `String.Empty` when calling the mehtod and will always end in beeing `"."`. Moreover it cannot be used outside of the method. – Olivier Jacot-Descombes Jul 20 '12 at 16:21
  • @JTA http://www.youtube.com/watch?v=e9mf3Bypyk8 – Mike Cole Jul 20 '12 at 16:45

5 Answers5

4

You said you don't want to keep the dots out side of Method (in the Method's class), then you must return the value from Method so that you can at least pass it in later on, thus persisting its state.

string Method(string dot = string.Empty)
{
   if(dot == "...") return string.Empty;
   else return dot + ".";
}

var result = Method(Method(Method(Method(Method(Method()))))) // etc...

EDIT: Your edited question does not make your initial problem more practical. It still suffers from the same problem: You want X but C# does not have X. Use C++ or VB.NET instead.

The answer to your question

"Is it possible to initialize a variable just once in this situation?"

is Sorry, NO!

Jake
  • 11,273
  • 21
  • 90
  • 147
  • 1
    I'll agree that the idea here is clever, but this is a bad solution. It loses the flexibility of the class member route, since the appending of the string only works while you keep a reference of the original string around. It's also difficult to read or maintain. – Tim Copenhaver Jul 20 '12 at 17:42
  • I arrived here with the same question, and realized as I read the thread that this is an ideal use case for a read-only static member that is initialized by the static constructor of a class. – David A. Gray Mar 11 '23 at 07:27
3

You could keep dots in your class, and initialize it when the class is created, i.e.

string dots = string.Empty; 
private void Method()
{
    if (dots != "...")
        dots += ".";
    else
        dots = string.Empty;
}
Ryan
  • 26,884
  • 9
  • 56
  • 83
  • 1
    Why increase the scope of dots beyond the method where it's needed? Also that does not avoid double initialization at all. – Eric J. Jul 20 '12 at 16:12
  • 2
    As a small side note of style, I'd recommend switching the if and else. It's easier to read if you avoid the negative if statement. – Tim Copenhaver Jul 20 '12 at 16:12
  • 3
    @Eric because it is obviously needed outside of the method. The method returns nothing, so the only way to get the result is from outside. Also, you need the scope of the variable to live beyond the scope of the method to be able to increment the dots. – Tim Copenhaver Jul 20 '12 at 16:13
2

In other languages (C++) you can declare static variables at any scope. This would solve your issue neatly but C# doesn't permit declaration of static variables within functions. This is actually a C# FAQ: Why doesn't C# support static method variables?.

This design feature means that you cannot do what you want in a conventional method. You might be able to do something particularly cunning with currying, but if you don't want to mess with the existing program structure, that's out. I'm sure that there's a way to write native code that would get you to what you want, but it feels like a bad idea.

Putting it simply, you're asking for data that persists outside of its scope. In C#, your chief (sole?) remedy is to increase that data's scope.

Reacher Gilt
  • 1,813
  • 12
  • 26
1

You are looking for persistent data between calls to the method, so you need a data element outside of your call. You don't have static local variables in C#.

Consider reading this Stackoverflow post.

Community
  • 1
  • 1
Les
  • 10,335
  • 4
  • 40
  • 60
0

Are you thinking of a static local variable as in C++? They are not supported in C#, as discussed here.

Community
  • 1
  • 1
Polyfun
  • 9,479
  • 4
  • 31
  • 39