Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is '@' allowed before any member variable (i.e. call to a function/Property) when it doesn't affects its value?

Tags:

c#

asp.net

I know '@' keyword is used for different purposes in C# as discussed here, but my question is different.

Suppose I am using @ConfigurationManager.AppSetting["DbConnectionString"] in place of ConfigurationManager.AppSetting["DbConnectionString"]. It still works in the same way.

So my questions are:

  1. Why is the '@' symbol allowed by the compiler here when it does not affect its value?
  2. Can the '@' symbol change the values in any scenario as mentioned above?

To make it more clear I want to add one more Example:

Suppose, I have a class 'ConfigurationLoader' that has a static function 'GetConfigurations' returns a list of strings.

Then,I can call it as List<string> ConnectionStrs=ConfigurationLoader.GetConfigurations();.

If I make it as List<string> [email protected](); then it still gives the same result. In such senario, I am asking above two questions.

like image 873
Sanjeev Rai Avatar asked Jun 04 '13 13:06

Sanjeev Rai


2 Answers

As you can probably tell from the flood of comments, there isn't really a good, satisfying answer to your question. I will give it a try, though:

1. Why is the '@' symbol allowed by the compiler here when it does not affect its value?

Because that's what the language specification says. The @ symbol before a token does not mean "The next token is a keyword but treat it like an identifer." That's not how the spec is written, so that's not how the language compiler works. Rather, it means "whatever the next token is, treat it like an identifier, even if it happens to be a keyword".

It's the same as saying, for example, "pretend blue were a color". That's easy to do, because blue is a color. Similar, saying "pretend myCollection is not a C# keyword" is easy -- it's not a C# keyword, so there's nothing to do.

What you're really trying to ask, I suspect, is:

1b. Why did the people who designed C# define the behavior of the @ symbol this way?

That question, I'm afraid, only someone who helped define C# can answer. We can guess, and the answer is almost certainly going to be the one several people already commented on: because that way was easier (to explain, document, implement, test, etc.) and had no downside. Well, apart from some mild confusion on the part of some developers. :)

Adding a requirement in the spec that the compiler do something upon "abuse" of the @ symbol means a lot of work. You have to define what it does (is it a warning? error?), you have to add correct, accurate, proofread, unambiguous language to the spec, you have to add code into the compiler to produce the new behavior, you have to document the new behavior, you have to write test scripts to exercise the new behavior, etc. All for a "feature" that has zero added benefit.

It does make the usage of @ redundant, but C# lets you do lots of redundant things, for various reasons. You can add redundant (), you can add redundant delegate constructors, you can add redundant accessibility keywords. And, as you can see, you can add redundant @'s all over the place, if you want.

2. Can the '@' symbol change the values in any scenario as mentioned above?

This one, we can answer: No. If you place @ before a token that's already an identifier, it will be treated as an identifier -- the exact same identifier the the compiler was going to reference anyway. You won't see any change in behavior, it's just extra typing.

like image 34
Michael Edenfield Avatar answered Oct 16 '22 13:10

Michael Edenfield


UPDATE: This question was the subject of my blog in September 2013. Thanks for the great question!


Can the '@' symbol change the values in any scenario as mentioned above?

No.

What's the feature we're talking about?

In C# if you preface any identifier with @ then the identifier is permitted but not required to be a keyword. This feature allowed developers to use reserved keywords as identifiers:

static void M(bool @unsafe) { ... }

and it allows you to emphasize that an identifier that might be confused with a contextual keyword is really an identifier:

@yield = 123.45;

That would be legal without the @ but it makes it clear that the developer did not mean yield return 123.45; here.

So why then is it allowed on identifiers that are not keywords?

Let's get into the wayback machine and go back to the world of C# 2.0. Let's suppose that the feature was the way you suggest: the @ can only go on reserved and contextual keywords. You write this program in C# 2.0:

class P
{
  static void Main()
  {
    int @yield = 123;
  }
}

Doesn't it seem a bit weird that this is a legal C# 2.0 program but not a legal C# 1.0 program despite using no features of C# 2.0?

The feature as it is designed allows you to share code between two teams that are using different versions of C#. And it allows you to have one person on the team try out C# 2.0 to see if it works while everyone else is still using C# 1.0. Your proposed feature makes both those scenarios nightmarish, and introduces a barrier to adoption of new versions of the language. Upgrading is expensive enough already; the language design team does not want to make it even more expensive.

The feature as it is designed also enables "future proofing". Suppose you are writing a program that generates other programs. You might as well make the generated program preface all of its identifiers with @ because you don't know what words will become keywords in future versions of C#.

Where can I read more about the keyword rules of C#?

http://ericlippert.com/2009/05/11/reserved-and-contextual-keywords/

like image 108
Eric Lippert Avatar answered Oct 16 '22 14:10

Eric Lippert