VB.NET: Как ссылаться на модуль VB.NET?
У меня есть модуль Utility, поскольку VB.NET не имеет статического класса, такого как С#, а Module - это статический класс в VB.NET. Причина, по которой я использую модуль, заключается в том, что я использую метод Extension и его можно использовать только в модуле.
Я не могу ссылаться на этот модуль, но если я поместил свой код в класс. Я могу ссылаться на него без каких-либо проблем. Что может быть причиной? Я пропустил С#.
Изменить: модуль находится внутри утилиты вызова библиотеки классов.
Ответы
Ответ 1
Я не могу ссылаться на этот модуль, но если я поместил свой код в класс. Я могу ссылаться на него без каких-либо проблем. Кто-нибудь знает, почему?
Поскольку модули в VB не являются классами и не могут использоваться для создания объектов. Скорее, они что-то похожее на пространства имен, с той разницей, что пространства имен не могут содержать функции напрямую. Таким образом, причина для модулей заключается в том, чтобы обеспечить способ логически группировать функции, которые не относятся к классу.
Это имеет большой смысл, если учесть, что не все логически принадлежит классу. Рассмотрим System.Math
. Нет абсолютно никаких оснований для того, чтобы сделать этот класс, кроме странного пуризма ООП.
Кстати, вы не можете ссылаться на статические классы в С# либо, по крайней мере, если я правильно понимаю, что вы подразумеваете под "ссылкой". Возможно, вы можете это прояснить.
Ответ 2
Вам нужно пометить модуль как общедоступный модуль.
Ответ 3
Компиляторы .NET могут использовать любой тип синтаксиса языка и превращать его в эквивалент .NET. Иногда есть один для одного соответствия, другой раз нет.
Используя .NET Reflector, вы можете увидеть, что действительно делает компилятор.
В VB.NET модуль существует из-за наследия, унаследованного от Visual BASIC и частично от Microsoft BASIC.
Компилятор VB.NET примет этот
Public Module CoreModule
Dim R As New System.Random(CInt(Microsoft.VisualBasic.Timer))
Public Function D(ByVal Roll As Integer) As Integer
Return R.Next(0, Roll) + 1
End Function
Public Function _1D6() As Integer
Return D(6)
End Function
Public Function _2D6() As Integer
Return D(6) + D(6)
End Function
Public Function _3D6() As Integer
Return D(6) + D(6) + D(6)
End Function
Public Function _4D6() As Integer
Return D(6) + D(6) + D(6) + D(6)
End Function
Public Function CRLF() As String
Return Microsoft.VisualBasic.ControlChars.CrLf
End Function
End Module
И превратите его в это (код для краткости оставлен)
Public NotInheritable Class CoreModule
' Methods
Shared Sub New()
Public Shared Function _1D6() As Integer
Public Shared Function _2D6() As Integer
Public Shared Function _3D6() As Integer
Public Shared Function _4D6() As Integer
Public Shared Function CRLF() As String
Public Shared Function D(ByVal Roll As Integer) As Integer
' Fields
Private Shared R As Random
End Class
В С# эквивалент это
public sealed class CoreModule
{
// Fields
private static Random R;
// Methods
static CoreModule();
public static int _1D6();
public static int _2D6();
public static int _3D6();
public static int _4D6();
public static string CRLF();
public static int D(int Roll);
}
Все, что имеет значение, заключается в том, что испущенная CIL корректно работает.
Эта возможность является основной причиной того, что многие старые программисты Visual BASIC 6 очень раздражены при изменении MS на языке. Например, ключевое слово Integer, испускающее Int32 вместо Int16.
Модули подвергаются воздействию других сборок, ссылающихся на исходный блок, если модуль объявлен публичным.
Ответ 4
Возможно, методы/подпрограммы не являются общедоступными? У меня была эта проблема один раз, и это позволило бы получить доступ к локальному коду в вашем классе, но не если он был вне вашего класса и помечен "Private".
Ответ 5
Я не понимаю, о чем вы спрашиваете.
У VB.NET есть статические классы, как в С#, потому что в VB.NET a Module
IS a static class
. Они одно и то же. Все, что вы можете сделать со статическим классом, который вы можете сделать с модулем. Возможно, вы не отметили свой общедоступный/частный/защищенный доступ правильно?
Ответ 6
Imports System.Web
Imports System.Web.UI
Module ResponseHelper
<System.Runtime.CompilerServices.Extension()> _
Public Sub Redirect(ByVal response As Net.HttpWebResponse, _
ByVal url As String, ByVal target As String, _
ByVal windowFeatures As String)
If String.IsNullOrEmpty(target) Or _
target.Equals("_self", StringComparison.OrdinalIgnoreCase) And _
String.IsNullOrEmpty(windowFeatures) Then
response.Redirect(url, target, windowFeatures)
Else
Dim page As Page = CType(HttpContext.Current.Handler, Page)
If page Is Nothing Then
Throw New InvalidOperationException("Cannot redirect to new window outside Page context.")
End If
url = page.ResolveClientUrl(url)
Dim script As String
If String.IsNullOrEmpty(windowFeatures) Then
script = "window.open(""{0}"", ""{1}"", ""{2}"";"
Else
script = "window.open(""{0}"", ""{1}"");"
End If
script = String.Format(script, url, target, windowFeatures)
ScriptManager.RegisterStartupScript(page, GetType(Page), "Redirect", script, True)
End If
End Sub
End Module