Alexander Matusiak
Alexander Matusiak

Reputation: 1828

Brackets following variable declaration

I'm unfamiliar with the following syntax and I was wondering what happens to the variable after it exits the braces:

public string method(int projectid)
{
    string result = string.empty;
    var service = _service;
    {
         result = service.dosomething(); //_service implements it's own Dispose
    }

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

Do the brackets that immediately follow _service: { /* etc */ } indicate that the service variable is only in scope for the .dosomething() method and that afterwards while doing X operation indicated by the result += block - that the garbage collector could round up service and garbage collect it?

Basically, I want to know what the brackets surrounding var result = service.dosomething() are telling the compiler to do with regards to service and _service.

Upvotes: 2

Views: 3674

Answers (7)

Christos
Christos

Reputation: 53958

The variable result is local in the { }. So you can't access it outside the service.

Your code wouldn't even compile, since you try to assign a value to a variable that hasn't been declared.

update

As I can understand by your post you might want to make use of a using statement for using your disposable object called service and you are asking about what happens under the hood.

Initially, that you want can be done like below:

using(var service = new ...)
{
    result = service.dosomething();
}

In the ... you will place the type of your service class.

If you do so, then this code will be compiled by the C# compiler to the following one

try
{
    ServiceType service = new ServiceType;
    result = service.dosomething(); 
}
finally
{
    if (service != null)
    ((IDisposable)service).Dispose();
}

I have given the name ServiceType to ... in order to write the above sample. Hence, you should place there the correct type.

As you see now the using statement is a syntactic sugar for calling the Dispose method of you Disposable object. As it is stated more thoroughly and formally in MSDN

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned. The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler. The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object)

Upvotes: 6

MarkO
MarkO

Reputation: 2233

Brackets indicate scope. Any variable inside it gets out of scope when program execution passes the end } bracket.

Now, if that variable was the only reference to an instance of an object, then yes, it becomes eligible for garbage collection. When the next garbace collection run is executed is indeterminate however.

In this case, the _service variable still holds a reference to the instance. So nothing will be garbage collected.

Dispose is never called by garbage collection. It must be either called from code directly or with a using statement. GC will call a finalizer if present, to close any unmanaged resources.

Upvotes: 1

david.pfx
david.pfx

Reputation: 10868

You are referring to the braces, or curly braces. Brackets are square things.

Braces establish a new local scope. Variables defined inside this scope are local to the scope.

A local variable that has a destructor will have that destructor executed on leaving the block.

With the code as currently written, neither of those things will happen.

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283614

It has NO EFFECT on service or _service.

My guess (based on the comment) is that this code used to look like

public string method(int projectid)
{
    string result = string.empty;
    using (var service = _service)
    {
         result = service.dosomething();
    }

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

and someone discovered that the object was getting used via _service after the using disposed it, and "fixed" the bug by removing using and adding a semicolon and a comment saying why service isn't disposed right here, leaving the braces as a useless vestige of the old buggy version.


NOTE: In fairness to the coder, perhaps it was originally using (var service = GetService()) and someone decided to reuse the service instance, turning the code into the buggy version presented above, which then evolved into the current version.

Upvotes: 7

Marv
Marv

Reputation: 119

Everytime you declare a varviable inside {} brackets, it is only view and acessable inside of this brackets. If you want to acess your var you have to declare it var result; in your method and initialize it in your brackets result = service.dosomething();

If you use it this way, you will be able to acess it.

Upvotes: 0

CodeCaster
CodeCaster

Reputation: 151588

This will print "barbaz":

public static void Main()
{
    string foo = "bar";

    // new scope
    {
        foo += "baz";
    }

    Console.WriteLine(foo);
}

Since foo is declared in the parent scope, it will be accessible in the child scope.

Upvotes: 1

Benji_9989
Benji_9989

Reputation: 173

Is Same as :

public string method(int projectid)
{
    string result = string.empty;
    var service = _service;
    //{
         result = service.dosomething(); //_service implements it's own Dispose
    //}

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

Upvotes: 3

Related Questions