What is the difference in the 3 types of variables and how do they behave in the compiler?

Asked

Viewed 172 times

12

For test questions, I made the following code:

static int valor1 = 10 / 5;

static int valor2() => 10 / 5;

static int valor3 => 10 / 5;

public static void Main()
{
    Console.Write($"{valor1}\n{valor2()}\n{valor3}");
}

And the exit was:

2
2
2

That is, there was no difference in the result. With that, my doubts are:

  • What is the difference in the 3 types of variables presented (if they are variables)?

  • All behave the same in the compiler?

Working here.

  • Everything seems whole to me, because you think there would be differences?

  • @Article The form in which they are created.

3 answers

12


static int valor1 = 10 / 5;

This is a static variable, probably the compiler will do the calculation and store in static area of memory the result.

static int valor2() => 10 / 5;

Here is a static method, again there may be an optimization with the ready calculation stored in static area, but it is less likely, so your invocation will run a simple algorithm. Since the method is internal and there are guarantees that it cannot be accessed from outside it is possible that the method is optimized and a call to the direct value is placed in place of the method call.

static int valor3 => 10 / 5;

Here is a property, ie a couple of access methods (in case you will only have the get) that will perform the operation when called. It is possible that an optimization is done as in the method.

I put in the Github for future reference.

Optimizations are not in specification, it’s just a possibility. Currently this occurs:

C..cctor()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: mov dword [0x1609da6c], 0x2
    L000d: pop ebp
    L000e: ret

C.valor2()
    L0000: mov eax, 0x2
    L0005: ret

C.get_valor3()
    L0000: mov eax, 0x2
    L0005: ret

Just returns 2 in the 3 cases as predicted. But I thought I could get more optimization by being an internal member and not public.

See on Sharplab.

  • I don’t know if it has much to do, but let’s go: From what I understand in your answer, the most optimized form is the first. Why? From the compiler code you left, it’s not what it looks like, since it has more code.

  • 1

    That’s why crunching code in a superficial way doesn’t work. Having more code does not mean that it consumes more processing cycles, does not indicate that there will be transfer bottlenecks of the various levels of memory, etc. In this case that code will even consume more processing, but only once before it is consumed and never again, the other codes will be executed every time you try to access the value.

11

static int valor1 = 10 / 5;    // Declaração de um campo.

static int valor2() => 10 / 5; // Declaração de um método estático utilizando membro de expressâo incorporada.

static int valor3 => 10 / 5;   // Declaração de uma propriedade utilizando membro de expressão incorporada.

The main difference is noted by the use of embedded expression members, which is nothing more than syntactic sugar introduced in version 6 of C#.

The compiler would convert to the following code (see for yourself using the tool Sharplab):

private static int valor1 = 2;

private static int valor3
{
    get
    {
        return 2;
    }
}

private static int valor2()
{
    return 2;
}

References:

6

In reality you are creating variables and methods and assigning values to them differently.

Like the first.

static int valor1 = 10 / 5;

Here you declare the variable valor1 as an integer and static and assign the value of a mathematical function to it 10 / 5.

In the second;

static int valor2() => 10 / 5;

You are creating a method and assigning a value through an expression (=>), see that you are not using a variable to access its value but calling the method valor2().

In the third;

static int valor3 => 10 / 5;

You create a variable and assign the value to it through the expression =>.

What is the difference in the 3 types of variables presented (if they are variables)? All behave the same in the compiler?

As shown above these are the differences.

All behave the same in the compiler?

No, as I specified each one has a different perincipalmente behavior the second the others have the way the value was assigned.

  • 1

    Marconcilio, this syntax is not lambda expressions. See https://docs.microsoft.com/pt-br/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members

  • 1

    @merchant, I edited.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.