2009-12-30 3 views
9

정적/공유 멤버의 가시성을 가진 VB.NET 및 C# (.NET2)의 상황에 직면했습니다. 그것은 VB.NET 나에게 조금 이상한 것 같다VB.NET 및 C# 가시성에서 정적/공유

public class A 
    { 
     private static A instance; 
     public static A Instance 
     { 
      get { return instance; } 
     } 

     public string Name { get { } } 
    } 

사용 : A.Instance.Name // 만 이름이 "볼 수"입니다


VB.NET :

Public Class A 
    Private Shared _instance As A 

    Public Shared ReadOnly Property Instance() As A 
    Get 
     Return _instance 
    End Get 
    End Property 


    Public ReadOnly Property Name() As String 
    Get 
     Return "" 
    End Get 
    End Property 

End Class 

사용법 :

A.Instance.Instance.Instance.Instance... 

// 공유 멤버

이는 마이크로 소프트 감독 또는 VB.NET "기능"입니다 .. 나는 무한으로 반복 할 수있는 클래스 공개처럼 행동?

+3

내 '왜 VB # C#이 아니야'의 목록 ;-) –

+5

@AdamRalph : 이것은시기 상조이며 반사되지 않을 것입니다. –

답변

19

VB에서 코드 이 경고를 나타냅니다.이 의미는 명백하게 다음과 같은 의미입니다.이 표기법을 사용하지 마십시오. VB에서

는 정적 멤버 엄밀히 말하면 이후, VB 이없는, 인스턴스를 통해 액세스 할 수 있습니다 static : VB는 회원이 같이 모든 인스턴스간에을 공유하는 것을 의미, 키워드 Shared있다 static에 대한 구성원이 이 아닌 인스턴스에 속하지 않습니다.

이제는 이러한 키워드 간의 의미있는 차이입니다. 이 두 가지 별개의 의미가 정확히 동일한 효과를 갖는 경향이 있습니다.

물론 C#의 static은 현재 VB.NET에서 Shared과 동일하지만 레거시가 다르며 VB의 Shared은 단순히 다른 기록을 가지고 있으므로 역사적으로 다른 의미를 갖습니다. 이 의미는 의미이므로 인스턴스를 통해 Shared 회원에 액세스하는 것이 절대적으로 의미가 있습니다. Option Strict Off (느슨한 입력)와 함께 사용하면

그것은 또한 의미가 있습니다 : 여기, 당신은 때때로 변수의 유형 모르지만 그래도 Shared 멤버에 액세스 할 수 있습니다.

Option Strict Off 
' … ' 
Dim o As Object = New A() 
' Somewhere else, we want to access a static member of A but we don’t know A: ' 
Dim instance = o.Instance 
+0

C#은 VB.NET이 VB 계열과의 "역사적인"호환성을 고려해야한다는 점을보다 정확하고 명확하게 보여줍니다. 어쨌든 C#에서는 정적 멤버의 가시성에 클래스 이름 및 클래스 인스턴스를 통해 중복을 허용하지 않습니다. 또한 Instance.StaticMember.StaticMember와 같은 필드 호출을 "무한하게"하는 것을 방지합니다. 이로 인해 클래스 인스턴스의 사용자가 당혹 스러울 수 있습니다. – serhio

0

C# 컴파일러는 개체의 인스턴스에 정적 속성을 참조하는 것을 허용하지 않습니다, 단지 형 자체에 : 액세스하기 위해 인스턴스를 사용하지만 지금, 당신은 선택의 여지가있어. 이것은 .NET CLR 제한이 아니라 C#입니다. VB.NET에서는 이것을 허용하지만 경고를 표시합니다.

+0

* .NET CLR 제한이 아닌 C#입니다. * 정적 멤버의 가시성을 복제하지 않기 때문에 클래스 이름 및 클래스 인스턴스를 통해이 제한 사항을 적용하는 것이 좋습니다. 또한 이것은 Instance.StaticMember.StaticMember.StaticMember.StaticMember.StaticMember와 같은 필드 호출을 "무한히"하는 것을 방지합니다 ... – serhio

+0

더 동의 할 수 없습니다. –

9

이것은 기능입니다. 이것은 버그가 아닙니다. VB는 설계대로 작동합니다. 정적 메서드가 인스턴스의 메서드로 처리 될 수 있는지 여부에 따라 언어가 다르게 선택됩니다. VB는 그것을 허용합니다. C++에서 허용됩니다. C#은 그렇지 않습니다.

다른 언어의 디자인 기준이 다르므로 결정이 서로 다릅니다.C# 디자인 팀에서는 불법 패턴을 의심스럽게 만드는 언어 정의를 매우 중요하게 생각합니다. 수신자 표현식을 계산할 때 부작용이 발생하지 않는 한, 정적 메소드에 수신자로 인스턴스를 전달하는 의미가 이 아니기 때문에 사용자가 의미없는 코드를 입력하도록 허용하는 이유는 무엇입니까?

VB 디자인 팀에서는 코드가 처음 입력했을 때으로 작동하는 것을 의미하는 것으로 평가합니다. 무언가가 조금 어색해 보이면 어쩌면 경고를해라. 그러나 그것을 허용하고 계속 나아 간다. 당신은 C#에서 정적 전화의 디자인에 더 미묘한 문제들에 관심이 있다면

, 여기에 흥미로운 문제이다 : 이것이 사실이라면 나는 그것을 추가 할 것입니다

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

+0

정말로, 내 인스턴스를 * 정적 * * 공유 *보다 더 * 간주했다. 싱글 톤 * 인스턴스 *와 하나의 인스턴스 *를 하나 더 가질 것으로 기대하지 않았다. – serhio