简体   繁体   中英

What can be defined outside any class in C#?

I heard that

  • in Java, everything is defined in classes, except classes themselves.

  • C# and Java are very similar languages.

So i thought that it is the same case for C#, until I saw two examples, where a enum type and a delegate type are not defined within any class:

using System; 
enum Color 
{ 
  Red, 
   Green, 
   Blue 
} 
class Test 
{ 
  static void PrintColor(Color color) { 
    switch (color) { 
      case Color.Red: 
        Console.WriteLine("Red"); 
        break; 
      case Color.Green: 
        Console.WriteLine("Green"); 
        break; 
      case Color.Blue: 
        Console.WriteLine("Blue"); 
        break; 
      default: 
        Console.WriteLine("Unknown color"); 
        break; 
    } 
  } 
  static void Main() { 
    Color c = Color.Red; 
    PrintColor(c); 
    PrintColor(Color.Blue); 
  } 
} 

and

using System; 
delegate double Function(double x); 
class Multiplier 
{ 
  double factor; 
  public Multiplier(double factor) { 
    this.factor = factor; 
  } 
  public double Multiply(double x) { 
    return x * factor; 
  } 
} 
class Test 
{ 
  static double Square(double x) { 
    return x * x; 
  } 
  static double[] Apply(double[] a, Function f) { 
    double[] result = new double[a.Length]; 
    for (int i = 0; i < a.Length; i++) result[i] = f(a[i]); 
    return result; 
  } 
  static void Main() { 
    double[] a = {0.0, 0.5, 1.0}; 
    double[] squares = Apply(a, Square); 
    double[] sines = Apply(a, Math.Sin); 
    Multiplier m = new Multiplier(2.0); 
    double[] doubles =  Apply(a, m.Multiply); 
  } 
} 

So what can be defined outside any class in C#?

Based on the above examples, can the definition of any type be defined outside any class?

Thanks.

According to the C# specification, in B2.6 Namespaces ,

  • compilation-unit:
    extern-alias-directives opt using-directives opt global-attributes opt
    namespace-member-declarations opt
  • namespace-declaration:
    namespace qualified-identifier namespace-body ; opt
  • qualified-identifier:
    identifier
    qualified-identifier . identifier
  • namespace-body:
    { extern-alias-directives opt using-directives opt namespace-member-declarations opt }
  • extern-alias-directives:
    extern-alias-directive
    extern-alias-directives extern-alias-directive
  • extern-alias-directive:
    extern alias identifier ;
  • using-directives:
    using-directive
    using-directives using-directive
  • using-directive:
    using-alias-directive
    using-namespace-directive
  • using-alias-directive:
    using identifier = namespace-or-type-name ;
  • using-namespace-directive:
    using namespace-name ;
  • namespace-member-declarations:
    namespace-member-declaration
    namespace-member-declarations namespace-member-declaration
  • namespace-member-declaration:
    namespace-declaration
    type-declaration
  • type-declaration:
    class-declaration
    struct-declaration
    interface-declaration
    enum-declaration
    delegate-declaration
  • qualified-alias-member:
    identifier :: identifier type-argument-list opt

According to rule namespace-member-declaration , those can be placed outside any class in C# is

namespace-declaration
type-declaration

Namely, namespace and type .

And type contains:

type-declaration:
class-declaration
struct-declaration
interface-declaration
enum-declaration
delegate-declaration

So the answer is namespace , class , struct , interface , enum , delegate declaration. Note I don't regard directives, like using-alias-directive , as definitions here.

You can find the spec file in C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC#\\Specifications\\1033 if you are using VS2017.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM