我最近更新了 Visual Studio,发现了顶级语句的这个新功能(对我来说这是新功能)。
Program据我了解,编译器完成了类和方法的定义Main,而无需您显式地键入它。
这很有用,但是我在定义新方法时遇到了麻烦。我想要在Program课堂上有一个方法。并用顶级声明来称呼它。这是一些示例代码:
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
public static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
Run Code Online (Sandbox Code Playgroud)
这给我带来了构建错误,因为公共静态修饰符无效。我认为它将其解释为 中的本地函数Main。我可以删除修饰符,但这只是示例代码,我的真实代码有更多方法和类。
我怎样才能做到这一点?我不应该为此使用顶级吗?
我希望这实际上与以下内容相同:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
}
public static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
}
Run Code Online (Sandbox Code Playgroud) 我通常将该属性设置[ExcludeFromCodeCoverage]为我的 Program 类,因为无论如何都无法对该类进行单元测试(或者也没有意义),因此它不会在覆盖率报告中显示为“缺失”:
[ExcludeFromCodeCoverage]
public static class Program
{
public static void Main(string[] args)
{
// do something awesome
}
}
Run Code Online (Sandbox Code Playgroud)
但对于高层的声明,我不知道如何处理这个问题。正如我在这里发现的那样,似乎无法设置属性: https: //stackoverflow.com/a/69962982/1099519
到目前为止,我坚持经典的类声明,但也许他们在单元测试代码覆盖率方面考虑了其他事情?
我正在摆弄顶级语句作为简单控制台应用程序的入口点,因为新的 .NET 6 模板使用它们作为默认值。
然而,正如语言规范非常清楚地指出的那样:
请注意,名称“Program”和“Main”仅用于说明目的,编译器使用的实际名称取决于实现,并且类型和方法都不能通过源代码中的名称引用。
那么,如果我无法引用隐式Program类及其Main()方法,是否可以编写单元测试来检查顶级语句本身的执行流程?如果是这样,怎么办?
我刚刚开始学习 C#,我创建了 C# 控制台应用程序。为了理解这些概念,我观看了如何为 C# 设置与代码的视频
dotnet new console当我在 VS code 终端中运行命令时,它会创建一个包含Program.cs文件的新项目。
在视频中,该Program.cs文件看起来像这样
// Program.cs
using System;
namespace HelloWorld
{
class Program
{
static string Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
Program.cs在我的 IDE 中看起来像,
// Program.cs
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Run Code Online (Sandbox Code Playgroud)
当我使用终端运行代码时,dotnet run它在我的计算机上完美运行。
当我创建一个新的 cs 文件时,它包含
// hello.cs
Console.WriteLine("hello world");
Run Code Online (Sandbox Code Playgroud)
运行后它说 Only one compilation unit can have top-level statements.
当我使用类方法和命名空间时
// hello.cs
namespace helloworld
{
class …Run Code Online (Sandbox Code Playgroud) 所以我写代码的时间不长,所以经验也不是很多,最近我在 replit.com 上遇到了一个问题,控制台会打印出:
error CS8803: Top-level statements must precede namespace and type declarations.
using System;
Run Code Online (Sandbox Code Playgroud)
有人能提出这个问题吗?这是我的代码,供任何想知道的人使用:
int English;
int Science;
int AverageCalc;
AverageCalc = Convert.ToInt32(Console.ReadLine());
class Program {
public static void Main (string[] args) {
Console.WriteLine("Write your math grades");
Math = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Write your english grades");
English = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Write your science grades");
Science = Convert.ToInt32(Console.ReadLine());
AverageCalc = (Math+English+Science/3);
}
}
if (AverageCalc > 80)
{
Console.WriteLine("You passed with A mark!");
}
else if (AverageCalc < 80)
{
Console.WriteLine("You passed …Run Code Online (Sandbox Code Playgroud) 我一直假设顶级语句生成的类是一个隐藏的、不可访问的类。例如:
System.Console.WriteLine(2);
partial class Program
{
public static string abc = "def";
}
Run Code Online (Sandbox Code Playgroud)
当使用默认分支或“C# 9:顶级语句(2020 年 5 月 27 日)”分支在 SharpLab.io 中运行时,生成的 C# 将是
// [ ... using and assembly attributes ... ]
internal static class $Program
{
private static void $Main(string[] args)
{
Console.WriteLine(2);
}
}
internal class Program
{
public static string abc = "def";
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,默认分支发出<Program>$not$Program和<Main>$not $Main。
但是,众所周知,您可以使用partial类Program来增强生成的类。修改代码以打印该字段...
System.Console.WriteLine(abc);
partial …Run Code Online (Sandbox Code Playgroud) 假设我有一个用 C# 9 编写的简单脚本,如下所示:
using System;
using System.IO;
// What to put in the ???
var exeFolder = Path.GetDirectoryName(typeof(???).Assembly.Location);
Run Code Online (Sandbox Code Playgroud)
之前,通过完整的程序,我们可以将该Main类用作“指示器”类。this并且this.GetType()不可用,因为从技术上讲它位于静态方法内。我现在怎样才能得到它?
我在输入问题时想到的解决方法是Assembly.GetCallingAssembly():
var exeFolder = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
Run Code Online (Sandbox Code Playgroud)
它适用于我的情况,但我只能获取Assembly,而不是TypeInfo代码正在运行的位置。
Program1.cs常规 C# 文件,运行良好。
Random numberGen = new Random();
int roll1 = 1;
int roll2 = 0;
int roll3 = 0;
int roll4 = 0;
int attempts = 0;
Console.WriteLine("Press enter to roll the dies");
while (roll1 != roll2 || roll2 != roll3 || roll3 != roll4 || roll4 != roll1)
{
Console.ReadKey();
roll1 = numberGen.Next(1, 7);
roll2 = numberGen.Next(1, 7);
roll3 = numberGen.Next(1, 7);
roll4 = numberGen.Next(1, 7);
Console.WriteLine("Dice 1: " + roll1 + "\nDice 2: " + roll2 …Run Code Online (Sandbox Code Playgroud) c# ×8
c#-9.0 ×3
.net ×1
.net-6.0 ×1
c#-10.0 ×1
entry-point ×1
file ×1
methods ×1
reflection ×1
testing ×1
unit-testing ×1