My question, to which the answer is not known to me is stated in the title, i.e.:
can a c# program start with a {
; if not, why not?
Everything that follows below details my research & thought process to date:
Note: referencing the "c# Language Specification 5.0";
code compiled with vs2015 community edition.
From §2.2.2 Lexical grammar, this sentence appears to imply that one can start with a {
because a {
is a token:
"Every source file in a C# program must conform to the input production of the lexical grammar (§2.3)."
§2.4 Tokens include punctuators and {
is a punctator [§2.4.5 Operators and punctuators]
However, §9. Namespaces begins "C# programs are organized using namespaces."
§9.1 Compilation units: "A compilation-unit defines the overall structure of a source file."
compilation-unit:
extern-alias-directivesopt using-directivesopt global-attributesopt
namespace-member-declarationsopt
"namespace-member-declarations of each compilation unit of a program contribute members to a single declaration space called the global namespace"
This compiles:
class Program
{
static void Main(string[] args)
{
}
}
This does not compile:
{
class Program
{
static void Main(string[] args)
{
}
}
}
So, although {
is a token, it does not contribute a member ... that is possibly why the compiler rejects the beginning {
.
However, the namespace-member-declarations are optional ~~ for that reason, perhaps the compiler should allow an intial {
.
this is a block:
{
}
not every block must be a something-block, see the last example below.
§1.5 Statements
"A block permits multiple statements to be written in contexts where a single statement is allowed.
A block consists of a list of statements written between the delimiters {
and }
."
one more example which compiles clean using blocks for scoping:
class Program
{
static void Main(string[] args)
{
{
System.Int16 integer = System.Int16.MaxValue;
}
{
System.Int32 integer = System.Int32.MaxValue;
}
}
}
However, the namespace-member-declarations are optional ~~ for that reason, perhaps the compiler should allow an intial {.
No, that's not what it being optional means - it means "there doesn't have to be one", not "you can have anything you like instead".
Basically, a compilation unit consists of the directives you've mentioned, global attributes, and member declarations. That's all that can appear at the top level. A block is not a member declaration (or a global attribute, or a directive) and so can't appear at the top level.
Here's another hint:
A block permits multiple statements to be written in contexts where a single statement is allowed.
A single statement isn't allow at the top level either. This isn't valid code:
using System;
Console.WriteLine("Nope, can't have a statement here.");
Again, it doesn't follow the grammar - it's not a member declaration.
Finally, even if blocks were allowed at the top level, they'd have to be changed for your code to be valid - because you're trying to declare a class within the block, which isn't valid.
See more on this question at Stackoverflow