将 C# 函数翻译成 vb.net

Translating C# functions into vb.net

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

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

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

等价于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");

这完全取决于您想要什么。 VB.NET 不提供静态 classes。相反,它提供模块,但这些模块并不完全等同于 static classes.

模块版本为:

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

class 版本为:

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

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

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

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

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

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

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

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

我个人认为 Visual Studio 中关于 VB.NET 模块成员使用的这种检查行为相当烦人和混乱。我更喜欢在调用前加上模块名称(为了编写自文档化代码并避免上述歧义),但我不想禁用 Visual Studio 中的“简化名称”hint/suggestion。因此,在 VB.NET 中实现模仿 C# 静态 class.

的东西时,我个人更喜欢 class 实现而不是模块实现

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