VB.NET의 클래스와 모듈


157

VB.NET에서 공유 멤버 함수가있는 클래스 대신 모듈을 사용하는 것이 허용 가능한 방법으로 간주됩니까?

모듈은 Visual Basic 6.0에서 남은 것처럼 느껴지고 더 이상 적합하지 않기 때문에 모듈을 피하는 경향이 있습니다. 반면, 공유 멤버 만있는 모듈과 클래스를 사용하는 경우에는 큰 차이가없는 것 같습니다. 내가 정말로 많은 것을 필요로하는 것은 아니지만, 때로는 그들이 간단한 해결책을 제시하는 상황이 있습니다.

당신이 어떤 식 으로든 의견을 가지고 있는지 궁금합니다.


10
모듈에 대한 흥미로운 점 중 하나는 기본적으로 내부에 선언 된 메소드 및 함수에 모듈의 보호 레벨이 있다는 것 Private입니다. 즉, 규정 자를 명시 적으로 추가하는 것을 잊어 버린 경우 실수로 메소드를 사용할 수 있습니다 . 클래스에서 기본 보호 수준은 개인 수준이므로 알지 못하는 경우 혼동 될 수 있습니다.
— yu_ominae

답변:


207

ModuleC # static클래스에 대응하는 VB 입니다. 클래스가 헬퍼 함수 및 확장 메소드 전용으로 설계되었으며 상속 및 인스턴스화 를 허용 하지 않으 려면을 사용하십시오 .Module

그건 그렇고, 사용 Module은 실제로 주관적 이지 않으며 더 이상 사용되지 않습니다 . 실제로 Module적절한 경우 를 사용해야합니다 . .NET Framework 자체는 여러 번 수행합니다 ( System.Linq.Enumerable예 :). 확장 메소드를 선언하려면 Modules 를 사용해야 합니다.


7
인스턴스 생성과 NotInheritable 수정자를 방지하기 위해 개인 생성자를 사용할 수는 있지만 매우 그렇습니다. 평범한 구형 모듈보다 약간 추악하지만 동일한 효과가 있습니다. 프레임 워크에서 모듈 사용에 대한 포인터에 감사드립니다. 내가 살펴볼 게
— Tom Juergens

8
후드 아래에서 [StandardModule] 속성을 가진 클래스로 컴파일됩니다. 또한 모듈을 사용하면 공유되지 않은 것들이 없어야합니다.
— Mehrdad Afshari

18
모듈은 C #의 정적 클래스와 다릅니다. 모듈의 메소드는 가져온 네임 스페이스에있는 경우 효과적으로 전역 적입니다.
— JaredPar

2
@JaredPar : 내 말이 잘못되었을 것입니다. VB가 C # 정적 클래스에 해당한다고 말해야합니다. 그 말에서 모듈을 사용하는 것이 C #에서 정적 클래스를 작성하는 곳이 의미가 있다고 말하려고했습니다.
— Mehrdad Afshari 2014 년

3
@Chiwda msdn.microsoft.com/en-us/library/bb384936.aspx 참조 : "확장 메서드는 모듈 내에서만 선언 할 수 있습니다."
— Mehrdad Afshari

34

모듈을 별도의 네임 스페이스에 붙이지 않는 한 모듈을 피하는 것이 좋습니다. Intellisense에서 모듈의 네임 스페이스의 모든 위치에서 모듈의 메소드를 볼 수 있기 때문입니다.

따라서 대신 어디에서나 팝업으로 ModuleName.MyMethod()끝나고 MyMethod()캡슐화가 무효화됩니다. (적어도 프로그래밍 수준에서).

그렇기 때문에 항상 공유 메서드를 사용하여 클래스를 만들려고 시도하는 것이 훨씬 좋습니다.


7
동의합니다. 현재 클래스와 모듈이있는 오래된 프로그램 (아마도 VB6-VB.NET 1 포트)을 작업 중입니다. 약 10 개의 서로 다른 모듈에는 수백 가지의 전역 변수, 하위 및 함수가 있으며, 그 위치와 수정 방법의 원인을 찾는 것은 지옥입니다.
— yu_ominae

좋아, 이것은 매우 오래되었지만 내 질문과 관련이 있습니다. 난 하지 비주얼 베이직 사람,하지만 난 그것으로 일해야한다. IntelliSense / ReSharper가 죽기 때문에 큰 클래스 (> 46,000 줄)를 분해하려고합니다. 모듈을 사용하고 큰 함수 덩어리를 자체 모듈로 리핑하는 것이 효과가있는 것처럼 보이지만 각 모듈에 자체 네임 스페이스를 제공 해야하는지 궁금합니다. 그럴까요? 즉, 모듈만으로 IntelliSense의 속도를 높이거나 네임 스페이스가 더 도움이됩니까?
— codah

27

모듈은 더 이상 사용되지 않으며 VB 언어로 많이 사용됩니다. VB.Net에서 확장 메소드를 구현하는 유일한 방법입니다.

정적 멤버가있는 모듈과 클래스에는 큰 차이가 있습니다. 현재 네임 스페이스에서 모듈을 사용할 수있는 한 모듈에 정의 된 모든 메소드에 액세스 할 수 있습니다. 실제로 모듈을 사용하면 전역 메소드를 정의 할 수 있습니다. 공유 멤버 만있는 클래스는 수행 할 수없는 작업입니다.

다음은 원시 COM 인터페이스와 상호 작용하는 VB 코드를 작성할 때 많이 사용하는 간단한 예입니다.

Module Interop
  Public Function Succeeded(ByVal hr as Integer) As Boolean
    ...
  End Function

  Public Function Failed(ByVal hr As Integer) As Boolean
    ...
  End Function
End Module

Class SomeClass
  Sub Foo()
    Dim hr = CallSomeHrMethod()
    if Succeeded(hr) then
      ..
    End If
  End Sub
End Class

4
확장 방법 ... 나는 항상 사용하려고하는 또 다른 훌륭한 기능이지만 실제로는 결코 돌아 가지 않습니다 .- 글쎄, 이것은 나에게 또 다른 좋은 기회를 제공합니다. 나는 전 세계 범위에 대해 조금 알고 있고, 전 세계적으로 사용 가능한 방법은 확실히 편리 할 수 ​​있지만, 그것들을 과도하게 사용하는 것에 대해서는 약간 불안합니다. 여하튼, 지금까지의 모든 대답은 내가 모듈을 기각해서는 안된다는 것을 말해줍니다. 올바른 환경에서 사용해야 할 이유가 있습니다.
— Tom Juergens

12

사용할 수 있습니다 Module. Module의 대체품으로 사용되지 않습니다 Class. Module자체 목적을 수행합니다. 의 목적은 Module컨테이너로 사용하는 것입니다

  • 확장 방법,
  • 특정 변수가 아닌 변수 Class또는
  • 에 맞지 않는 변수 Class.

Module유사한되지 않습니다 Class때문에 당신은 할 수 없습니다

  • 에서 상속 Module,
  • 구현 InterfaceA를을 Module,
  • 의 인스턴스를 만들 수도 없습니다 Module.

내부 뭐든지 Module직접 내에서 액세스 할 수 있습니다 Module을 참조하지 않고 조립 Module이름으로. 기본적으로 a의 액세스 수준 Module은 Friend입니다.


11

클래스

  • 클래스는 객체 로 인스턴스화 될 수 있습니다
  • 인스턴스화 된 각 개체마다 개체 데이터가 별도로 존재합니다.
  • 클래스는 인터페이스 를 구현할 수 있습니다 .
  • 클래스 내에 정의 된 멤버는 클래스 의 특정 인스턴스 내에서 범위 가 지정 되며 개체 수명 동안 만 존재 합니다 .
  • 클래스 외부에서 클래스 멤버에 액세스하려면 Object.Member 형식의 완전한 이름 을 사용해야 합니다.

모듈

  • 모듈 은 객체로 인스턴스화 할 수 없습니다 . 표준 모듈 데이터의 사본이 하나만 있기 때문에 프로그램의 한 부분이 표준 모듈의 공용 변수를 변경하면 전체 프로그램에서 볼 수 있습니다.
  • 모듈 내에 선언 된 멤버는 기본적 으로 공개적으로 액세스 할 수 있습니다 .
  • 모듈에 액세스 할 수있는 모든 코드로 액세스 할 수 있습니다.
  • 즉, 표준 모듈의 변수는 프로젝트의 어느 곳에서나 볼 수 있고 프로그램 수명 동안 존재하기 때문에 효과적으로 전역 변수입니다.

6

내 VB.NET 클래스 중 하나에 모든 공유 멤버가 있으면 일치하는 (또는 다른 적절한) 네임 스페이스가있는 모듈로 변환하거나 클래스를 상속 할 수없고 구성 할 수 없습니다.

Public NotInheritable Class MyClass1

   Private Sub New()
      'Contains only shared members.
      'Private constructor means the class cannot be instantiated.
   End Sub

End Class

3
그리고 여기에 네임 스페이스 모듈에 대한 구문입니다 : Imports <whatever>당신은 어떤 수입이있는 경우, Namespace MyCoolModule, Public Module MyCoolModule, <멤버 없이 Shared >, End Module, End Namespace.
— Rory O'Kane

0

모듈은 열거 형과 일부 전역 변수, 상수 및 공유 함수를 저장하는 데 적합합니다. 그것의 아주 좋은 것 그리고 나는 종종 그것을 사용합니다. 선언 된 변수는 전체 프로젝트에서 볼 수 있습니다.


0

당신은 있어야 당신이 확장 방법을 만드는 경우 (오히려 급 이상) 모듈을 사용합니다. VB.NET에서는 다른 옵션을 알지 못합니다.

모듈 자체에 강하기 때문에 보일러 Sub New()모듈 코드를 추가하여 임베디드 어셈블리를 한 번에 해결하는 방법을 모색하는 데 몇 시간이 걸렸습니다. (모듈)과 Shared Sub New()(클래스)가 같은지 알았습니다. (나는 모듈에 호출 가능한 것이 있다는 것을 몰랐다 Sub New()!)

그래서 난 그냥 던져 EmbeddedAssembly.Load및 AddHandler AppDomain.CurrentDomain.AssemblyResolve거기에 선을 밥 삼촌이되었다.

부록 : 아직 100 % 체크 아웃하지는 않았지만 Sub New()클래스와 모듈에서 다른 순서로 실행 되는 잉크 링이 있습니다 . 단지 피하기 위해 선언을 외부에서 내부 메소드로 옮겨야한다는 사실에 의해 진행됩니다. 오류.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.