Why can’t I declare an attribute using the var keyword?

Asked

Viewed 675 times

16

The keyword var allows me to declare typed variables, and allows variables to be defined implicitly.

Example: var i = 10;

The compiler will assume that my variable i is of the whole type int.

Therefore, because the compiler does not allow me to use the keyword var for attribute statements within a class?

See this example for illustration:

class ClasseExemplo 
{
    public var atributo; //Este atributo poderia ser declarado de forma implícita.

    public ClasseExemplo() 
    {
        this.atributo = null;
    }
}

The above example returns the following error:

Error 1 The type or namespace name 'var' could not be found (are you Missing a using Directive or an Assembly Reference?)

If this way I can’t declare an attribute that can be of any type, there could be another way to do this?

3 answers

14


The simple answer: because the language specification says that you should not infer in this case. That is, the language creators thought it was not worth doing this. There are languages that infer.

Detailing

To achieve this the compiler would be much more complicated. Some situations are very difficult or even impossible to infer. Of course I could infer to some extent and require the type in other cases, but they preferred not to invest in it (there are proposals to do so), because some members of the class are part of her contract, in which case it is better to be more explicit, although this does not convince me much. The problem is the huge work to do right.

In fact some situations could make the compilation slow and confusing. There are cases of chained and even cyclical references. There are cases that to compile that first need to compile other drives to ensure that it is with the most up-to-date code, there are static boot cases where order may not be guaranteed.

To more official response can be obtained with one of the compiler creators.

It may have become more complicated with the possibility to initialize the property also since C# 6.

Use var doesn’t mean you can use any kind, just means you don’t have to type the type.

What is being called attribute is actually a field. Attribute is something else.

  • Today C# has the option of using the static type Dynamic, which would work in the desired way, but I do not see this as a good programming practice, because the object is open to receive any type of data (including complex objects) and the non-use of a contract can cause problems, for example if the user calls a non-existent method or attribute of the instantiated object, the compiler allows the call and compiles without errors, but in the execution it does not find and throws an exception. See Dynamic in the Microsoft documentation: https://msdn.microsoft.com/pt-br/library/dd264736.aspx

  • 1

    Doesn’t look like this is the way you want it.

  • 2

    Not to mention that as you would enter the return type of the method that returns atributo? Int, String? If a type attribute could be defined var in the class, automatically it could not have methods that return it.

  • @Guilhermelautert would have to be dynamic. But in fact the dynamic can be converted to a static type, of course it would no longer be the class field.

  • @bigown Exactly, why would not logica use var in a class.

5

Look, as already said in the @Maniero reply

Using var doesn’t mean you can use any type, it just means you don’t need to type.

In simplest terms this means that it is the compiler that chooses the type of the variable for you. You may ask, "But how does it do that?"

He does this by analyzing what is on the right side of the statement. Example:

var i = 10;

10 is integer, so the variable i be the type int. If in sequence I try to do

i = "qualquer coisa";

I’ll get the bug

Cannot implicitly Convert type 'string' to 'int'


If this way I cannot declare an attribute that can be of any kind, there could be another way to do this?

Yes, you can use dynamic for that reason. Dynamic gives you the freedom to do what you want - a property that can have its type changed at any time. See an example:

public static void Main()
{
    dynamic i = 10;

    WriteLine(i.GetType()); //output: System.Int32

    i = "teste";

    WriteLine(i.GetType()); //output: System.String
}

Keep in mind that this may (and will) give you some trouble if you’re not sure what you’re doing. Maybe, in more detail, we can help you better with this, but only with what you said is hard.

4

The first problem is that implicit type variables have to be immediately initialized(and not valid = null).

It’s like @Maniero said Usar var não significa que pode usar qualquer tipo, significa apenas que não precisa digitar o tipo.

If in the scope of a method you have var atributo = 5; atributo = "string"; immediately you will receive an error of compilation and not of execution!

But even if you did

class ClasseExemplo 
{
    public var atributo = 5;

}

Cannot declare class variables with implicit type .

It works that way :

First, he maps all the classes, class attributes, method statements... and then he analyzes the scope of the methods and it is in the scope analysis of the methods, based on what he already knows about the first stage that the type inference for the var occurs. That is, for this to work they would have to rewrite the compilation method. ( what they could implement , but chose not to do).

An opinion on the issue addressed in article , that on one of the topics talks about the difficulty of the compiler treating vars referencing other implicit types in string is that they could specify that a var cannot reference another implicit type in class attributes.

The limitation is probably due to lack of interest .

Browser other questions tagged

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