10

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> ConnectionStrs=@ConfigurationLoader.GetConfigurations(); then it still gives the same result. In such senario, I am asking above two questions.

Community
  • 1
  • 1
Sanjeev Rai
  • 6,721
  • 4
  • 23
  • 33
  • I'm not sure but it would make sense to me if @ directly modified a variable, whereas without @ it is calling a function which that variable type holds in order to change the variable (as opposed to just editing the memory). Just a guess, interesting question though! – XtrmJosh Jun 04 '13 at 13:56
  • Duplicate, as @Xander linked to. Also see: http://msdn.microsoft.com/en-us/library/aa691090(v=vs.71).aspx. I just explicitly declares a string literal. – Andrew Grothe Jun 04 '13 at 13:59
  • @Xander: as above link suggest, The prefix "@" enables the use of keywords as identifiers, but I am asking it in a different scenario. like, suppose I am using it as `string s=@ConfigurationManager.AppSetting["DbConnectionString"];'. Here I am not convering any keyword into identifire. – Sanjeev Rai Jun 04 '13 at 14:05
  • @SanjeevRai In that context it's superfluous, but not harmful. – Servy Jun 04 '13 at 14:06
  • Actualy, I was already affraid that I will not be able to present this question in too good manner to make it understandable for everyone. How can I reopen this question? – Sanjeev Rai Jun 04 '13 at 14:17
  • 3
    It's difficult to answer "why" questions, but it's most likely because there is no added benefit to making the C# compiler more complicated by only allowing the @ prefix in certain cases. Adding it to an identifier that does not need it will not change its values. – John Rasch Jun 04 '13 at 14:19
  • 2
    @JohnRasch Mr. Lippert puts it best ... *Error detection is expensive and difficult and so like any feature, error detection algorithms must be prioritized against other features in terms of their costs and benefits. The benefit of such an error detector is very small because this is highly contrived code, and the consequence of the error is obvious.* - http://stackoverflow.com/questions/16779479/is-it-possible-to-define-valid-c-sharp-interface-that-cannot-be-implemented/16779533#comment-24201135 – Alex Jun 04 '13 at 14:22
  • Why? Because the specification says so! It's `@identifier-or-keyword`, not `@keyword`. For more of a "yeah, but why did they make it that way?" see John Rasch's comment. – Tim S. Jun 04 '13 at 14:32
  • 1
    Voting to reopen this question as the question it "duplicates" is actually completely different. This question asks why `@` is still valid when it is *not* used for escaping keywords. – Ant P Jun 04 '13 at 14:34
  • @AntP - I think that question should be closed as well as "not constructive". – mbeckish Jun 04 '13 at 14:41
  • @mbeckish I disagree - even if the correct answer is simply that it's a redundant feature, the question is still valid. Either way, it's not a duplicate. – Ant P Jun 04 '13 at 14:43
  • @AntP I agree. I voted to reopen since I do not agree with the closing reason at all. If people will decide to close it as nonconstructive afterwards, then so be it. – SimpleVar Jun 04 '13 at 14:45
  • 3
    @AntP - I often see questions that boil down to "Why did the Microsoft developers choose x when implementing feature y?" closed as not constructive. Those kinds of questions are really only answerable by the developers themselves, unless there is a blog post or some other public reference for what their thought processes were at the time. – mbeckish Jun 04 '13 at 14:46
  • @John Rasch, I agree to your answer of my 'Why' question. – Sanjeev Rai Jun 04 '13 at 14:48
  • 1
    Also, this post needs to be reworded for clarity if it is really asking about why the developers chose to allow verbatim identifiers that are not keywords. The title and the numbered questions keep referring to the value of the variable, which has nothing to do with this. – mbeckish Jun 04 '13 at 14:49
  • @mbeckish, I am very Pleased that finally someone has understood what I am exactly asking about? Thanks for above comment. – Sanjeev Rai Jun 04 '13 at 14:52
  • @mbeckish There is a distinction, though, in that most of those questions boil down to design decisions, whereas this one seeks an empirical answer - "What is its function," rather than "Why was it designed this way?" (see 2.) The answer that it *has no function* is entirely valid and answers the question perfectly by disambiguating between the two code samples - the answer is that they are equivalent. – Ant P Jun 04 '13 at 14:53
  • @mbeckish some such questions are closed, but many are not. And we should not forget that one of the people who *helped write the compiler* frequently pops in to give actual, authoritative answers to such questions when the whim takes him. – Michael Edenfield Jun 04 '13 at 15:08
  • @MichaelEdenfield - Yes, it certainly is a judgment call about what should be closed and what shouldn't. Which is why it is a voting system. The crowd will determine the fate of this question and all others. – mbeckish Jun 04 '13 at 15:11
  • @mbeckish true. also, lets not forget that VTC isn't the only option. Even if this question were on-topic that doesn't make it "good", and one could downvote it as such :) – Michael Edenfield Jun 04 '13 at 15:12
  • @MichaelEdenfield - Downvoting has a specific meaning (as seen by hovering over it), as do each of the closing options. What makes this site different than other forums is that it is curated by its users, so that future users have less noise to wade through when looking for a specific answer. We certainly don't want to discourage people from asking questions, since that is what provides the content for this site. Maybe in the future they can come up with a better way to encourage people to improve their questions without scaring them off. – mbeckish Jun 04 '13 at 15:21
  • @Ant - The very title of the question begins with 'Why' and not 'What' – Chris Dunaway Jun 04 '13 at 15:27

4 Answers4

24

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/

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
6

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.

Michael Edenfield
  • 28,070
  • 4
  • 86
  • 117
  • 1
    Though it is often the case that the answer to "why?" questions is "because it was easier this way", this is actually one of the rare cases where there is a solid design principle at work here. C# was designed to *support development environments that contained multiple versions of the language in common usage*. This feature facilitates those scenarios. See my answer for details. – Eric Lippert Jun 04 '13 at 15:57
  • Your answer is also very helpfull alog with @Eric Lippert's. – Sanjeev Rai Jun 05 '13 at 04:36
0

The question you referenced answers your question. In this context, the @ tells the compiler that the next symbol is an identifier, no a keyword. You don't need it for ConfigurationManager, but it can still be used. Here is an example of where it would be required:

class @class
{
    public @class()
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        @class c = new @class();
    }
}
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • This answer has no information that isn't in the question itself. He asked why you're able to do this, you just stated he can. That he asked the question means he obviously already knows all of this. – Servy Jun 04 '13 at 14:01
0

You can use the @ symbol to use reserved keywords as simple variable names, such as this:

int @for = 10;

Console.WriteLine(@for); // 10

Just the same, you could have a variable named @hello instead of hello, even though hello isn't a reserved keyword that requires the @ prefix in order to use it as a variable name.

Edit to state the real reason that it is allowed when not used on a reserved keyword.

Two possible reasons:

  1. The @ was supposed to be allowed only on reserved keywords (and escaping strings), but someone forgot an if and others didn't care.
  2. The @ was supposed to be allowed on reserved keywords, and nobody cared in the first place, about whether it will be used in others ways as well.
SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • This answer has no information that isn't in the question itself. He asked why you're able to do this, you just stated he can. That he asked the question means he obviously already knows all of this. – Servy Jun 04 '13 at 14:00
  • 1
    "... to use reserved keywords as simple variable names" - is that not a reason? And doesn't the after-code text mean that it can also be used when unneeded, which is why the compiler allows it? The REAL WHY is obviously decisions that were made when sugaring-up the language. Some dude said "hey, we should be able to do this and that". Whats really wrong with my answer? – SimpleVar Jun 04 '13 at 14:01
  • That's not a reason why the compiler allows you to use it for non-reserved keywords, which is what the question is. The answer isn't wrong, it's just repeating the question itself in the form of an answer. That's not helping anyone. – Servy Jun 04 '13 at 14:02
  • 1
    It is just like the `\\` escape. You can escape characters that do not require escaping. You can unreserve names that are not keywords. Why? Why chair. – SimpleVar Jun 04 '13 at 14:04
  • 4
    There are many questions in SO that do not require any "qualification to answer" them, simply thanks to the fact that there isn't one answer, or any. Can you phone the developers, ask them for the reason? Can you tell me why we have `foreach` instead of `forall`? You're flaming for no reason. – SimpleVar Jun 04 '13 at 14:06
  • I didn't answer the question because I *don't* know why the developers didn't allow this. You've posted an answer to the question even though you didn't actually answer it at all. If you *do* know the answer, but just didn't include it in your post, then you should edit it into your answer. If you *don't* know the answer, then it would probably be best to delete your post since it doesn't answer the question. – Servy Jun 04 '13 at 14:08
  • @Servy - To me, it doesn't sound like the OP understands the usage of @ and is asking why the language designers made certain choices. It sounds like the OP is confused about its dual usage for string escaping and variable names. In the OP's 2 numbered questions, he asks why it is valid to have @ before the variable name when the **value** of the variable is not being affected. – mbeckish Jun 04 '13 at 14:11
  • 1
    @Servy I've edited my answer as you suggested, making my answer complete (but mainly adding humor). – SimpleVar Jun 04 '13 at 14:11