C# 等效于 VB 'module'

C# Equivalent for VB 'module'

在 Visual Basic 中,您可以使用模块作为存储 'loose' 代码的地方,这些代码可以是可以从应用程序的其他地方访问的方法和变量,而无需首先初始化某些东西,并且变量状态可以设置或更改并将始终保持该值。

我发现最接近的是 C# 中的静态方法,作为 public class 的一部分,但是它的缺点是变量不可全局访问,或者在内部 settable/gettable 如果变量是静态的。

以存储在空白模块中的VB中的以下简单代码为例。

Private iCount as Integer = 0

Public Sub Increment()
  iCount = iCount + 1
End Sub

Public CheckModulus() As Boolean
  If iCount % 6 == 0 Then
    Return True
  Else
    Return False
  End If
End Sub

现在,你有一个 class,从那个 class,你可以这样调用 CheckModulus()

Public Class Fruits

   Public Static Function ExactBunches() As String
      If CheckModulus() Then
         Return "You have an exact amount of bunches"
      Else
         Return "You need more fruits to make a bunch"
      End If
   End Function

End Class

现在我通过一些 hack 和 slash 意识到,您可以将 iCount 移动到 'settings',并在应用程序启动时重置它等,但请记住这是一个非常简单的示例来说明便利性能够拥有一套全球代码。过去我发现它最有用的地方是在创建 UserControls 或自定义 classes 时。此外,目的不是让所有东西都可以全局访问,而是让某些方法和变量可以全局访问,而其他方法和变量只能从模块内部访问。例如,虽然 CheckModulus()Increment()(全局方法)都可以修改和获取 iCount 值,但 iCount 不能全局访问,就像使用模块中的私有定义方法。

所以大泡菜是这样的:

What is the functionally equivalent code type in C# to VB & VB.NET's module ?

由于这个简单问题的复杂性,我觉得我应该为 'just in case there is no answer' 答案强加一个布尔值,如下所示。

If, there is nothing functionally equivalent, then what sort of clever hack or workaround (aside from using settings, or external storage like the registry, database, files, etc), to make this happen or something VERY very close ?

像这样的静态 class 相当于您的 VB 代码:

public static class MyModule
{
    private static int iCount = 0;   // this is private, so not accessible outside this class

    public static void Increment()
    {
        iCount++;
    }

    public static bool CheckModulus()
    {
        return iCount % 6 == 0;
    }

    // this part in response to the question about async methods
    // not part of the original module
    public async static Task<int> GetIntAsync()
    {
        using (var ms = new MemoryStream(Encoding.ASCII.GetBytes("foo"))) 
        {
            var buffer = new byte[10];
            var count = await ms.ReadAsync(buffer, 0, 3);
            return count;
        }
    }
}

然后您可以这样称呼它(并且 iCount 的值确实持续存在,因为它是静态的):

    // iCount starts at 0
    Console.WriteLine(MyModule.CheckModulus());   // true because 0 % 6 == 0
    MyModule.Increment();                         // iCount == 1
    Console.WriteLine(MyModule.CheckModulus());   // false
    MyModule.Increment();                         // 2
    MyModule.Increment();                         // 3
    MyModule.Increment();                         // 4
    MyModule.Increment();                         // 5
    MyModule.Increment();                         // 6
    Console.WriteLine(MyModule.CheckModulus());   // true because 6 % 6 == 0
    Console.WriteLine(MyModule.GetIntAsync().Result);   // 3

A fiddle - 使用异步静态方法更新

您可以使用 static class. You can also initialise these using a static constructor.

public static class MyStuff
{
    //A property
    public static string SomeVariable { get; set; }

    public static List<string> SomeListOfStuff { get; set; }
    //Init your variables in here:
    static MyStuff()
    {
        SomeVariable = "blah";
        SomeListOfStuff = new List<string>();
    }

    public static async Task<string> DoAThing()
    {
        //Do your async stuff in here
    }

}

并像这样访问它:

MyStuff.SomeVariable = "hello";
MyStuff.SomeListOfStuff.Add("another item for the list");