需要帮助将 C# 翻译成 VB

问题描述

enter image description here

我需要帮助转换部分代码。主要是:

private static void SetProvider(ServiceCollection collection)
     => _service = collection.BuildServiceProvider();

和它下面的行。这用于使用 discord.Net 和音乐库 Victoria 的不和谐机器人。有人也可以告诉我这实际上是什么吗?只是一个附带问题。这使用静态类,并且在 VB.Net 上没有任何称为静态的东西,那么这里最好的调用是什么?我看过这里的其他一些帖子,讨论是使用 NonInheritable 类还是 Module。有什么区别?什么时候用哪一个更好?

解决方法

这取决于你到底想要什么。 VB.NET 不提供静态类。相反,它提供了模块,但这些模块并不完全等同于静态类。

模块版本为:

Public Module ServiceManager
  Private _service As IServiceProvider

  Public Sub SetProvider(collection As ServiceCollection)
    _service = collection.BuildServiceProvider()
  End Sub

  Public Function GetService(Of T As New)() As T
    Return _service.GetRequiredService(Of T)()
  End Function
End Module

课程版本为:

Public NotInheritable Class ServiceManager
  Private Sub New()
  End Sub

  Private Shared _service As IServiceProvider

  Public Shared Sub SetProvider(collection As ServiceCollection)
    _service = collection.BuildServiceProvider()
  End Sub

  Public Shared Function GetService(Of T As New)() As T
    Return _service.GetRequiredService(Of T)()
  End Function
End Class

使用类实现时,必须小心地将所有成员标记为Shared。此外,您可以考虑以下事项:

  • 将类声明为 NotInheritable,因为 VB.NET 模块和 C# 静态类都不能继承。 (顺便说一下,相应的 C# 关键字是 sealed,但它永远不会在此上下文中使用,因为 C# 确实支持静态类。)
  • 为类创建一个私有(默认)构造函数。这将确保您无法实例化该类。 VB.NET 模块和 C# 静态类也无法实例化。

使用 VB.NET 模块更直接一些,但请记住,VB.NET 模块有一些怪癖。在访问模块的成员时,通常不需要在它前面加上模块名称。假设您有某种名为 MyService 的服务类,并且您已将 ServiceManager 实现为模块。那么你不需要像这样调用它:

Dim svc As MyService = ServiceManager.GetService(Of MyService)()

相反,你可以这样称呼它:

Dim svc As MyService = GetService(Of MyService)()`.

在使用前一种方法时,Visual Studio 实际上建议简化名称,将其更改为后一种方法。但是,当您随后添加另一个导入的命名空间时,该命名空间也恰好包含一个具有 GetService(Of T)() 方法的模块,您将收到一个错误,指示 GetService 不明确,在这种情况下,您将被强制 以模块名称作为前缀(如前一种方法)。

我个人认为 Visual Studio 中关于 VB.NET 模块成员使用的这种检查行为相当烦人和令人困惑。我更喜欢使用模块名称作为调用前缀(为了编写自记录代码并避免上述歧义),但我不想禁用 Visual Studio 中的“简化名称”提示/建议。因此,在 VB.NET 中实现一些模仿 C# 静态类的东西时,我个人更喜欢类实现而不是模块实现。

或者甚至更好:我会避免静态类设计并尽可能切换到“常规”类设计。使用类实例有几个优点,例如使用 composition(这也是许多流行的行为设计模式中使用的重要技术)、简化的模拟/单元测试以及总体上较少的副作用。

,

等效的 VB.NET 是:

Private Shared Sub SetProvider(collection As ServiceCollection)
    _service = collection.BuildServiceProvider()
End Sub

C# 表达式体只是一个单一的表达式体方法,MS Docs 例如以下是等效的:

void Greet()
{
    Console.WriteLine("Hello World");
}

// Same as above

void Greet() => Console.WriteLine("Hello World");