2009-12-27 3 views
0

나는 이상한 상황에 처해있다. 항목 객체의 배열 될 핵심 클래스의 속성의이상한 VB.NET 배열 속성 상황

Public Class Entry 

End Class 

Public Class Core 

End Class 

하나 :

나는이 두 개의 클래스가 있습니다. 어떻게 선언 할 수 있습니까?

외부에서이 배열을 변경 (추가/제거)하는 유일한 방법은 AddEntry (Ent Entry Entry) 및 RemoveEntry (ID As String)의 두 가지 기능을 사용해야합니다. 여기서 AddEntry 함수를 호출하는 사람은 Entry 객체를 생성하고 전달해야합니다. 기존 배열에 추가됩니다.

그러나, 엔트리 배열이 같은 인쇄 또는 무엇이든하고 통해 반복을 위해, 외부에서이 같은 액세스 할 수 있어야합니다 : 혼자 기능을 통해 수정을 속성으로 배열을 표시 할 수 있습니다 만, 제한

' core1 is a valid Core object 
For Each Ent As Entry In core1.Entries 
    MsgBox(Ent.SomeProperty) 
Next Ent 

이 가능 ? Add 및 Remove 함수 내부의 로직은 setter 또는 getter 내부에있을 수 있지만 추가하려는 사람은 하나의 Entry 객체 만 전달해야한다는 것을 알고 있습니다.

당신은 배열에 대한 읽기 전용 액세스 권한을 가지고 있지만 수정하기 위해 객체를 생성하고 ID를 보내거나 ID를 제거하십시오. 전체 배열에 대해 신경 쓰지 마라.

나는 의미가 있기를 바랍니다.

답변

1

왜 배열로 노출 하시겠습니까?

내가 수행 할 작업은 목록을 내부적으로 사용하여 항목을 저장하는 것입니다. (목록은 개인 목록입니다.) 개인 목록을 조작하는 데 필요한 공용 메서드 (AddEntry/RemoveEntry/...)를 만듭니다.

그런 다음 List를 노출하지만 읽기 전용으로 공개 속성을 만듭니다. 즉, 해당 속성은 ReadOnlyCollection 인스턴스를 반환해야합니다. 이처럼 :

(나는 그것을 C#으로 알고 있지만, 주요 언어 ''내이야 '- VB.NET로 변환 너무 게으른 조금)

public class Core 
{ 
    private List<Entry> _entries = new List<Entry>(); 

    public void AddEntry(Entry entry) 
    { 
     _entries.Add (entry); 
    } 

    public ReadOnlyCollection<Entry> Entries 
    { 
     get { return _entries.AsReadOnly(); } 
    } 
} 

편집 : VB 닷넷 버전은 개인 목록을 유지하고 대신 IEnumerable을 반환 할 수 있습니다 에 의해 MarkJ

Imports System.Collections.ObjectModel 
Public Class Core 
    Private _entries As New List(Of Entry) 

    Public Sub AddEntry(new As Entry) 
    _entries.Add (new) 
    End Sub 

    Public ReadOnly Property Entries() As ReadOnlyCollection(Of Entry) 
    Get 
     Return _entries.AsReadOnly 
    End Get 
    End Property 
End Class 
+0

+1 이봐, 아무 문제가 VB로 변환하는 방법을 알아낼거야 :) 코드 주셔서 감사. 나는 그것이 작동하게 할 수 있는지 알게 될 것이다. –

+0

일반 배열을 ReadOnly로 반환 할 수 있습니까? 항목을 항목으로 희석하십시오. 항목을 ReadOnly로 반환 할 수 있습니까? 또는 List, ArrayList 또는 이러한 객체에서만 사용해야합니까? –

+0

그러나 배열을 내부적으로 사용하려는 이유가 있습니까? 나는 그것을 복잡하게 만들 것이라고 생각합니다. 아마 생성자에서 배열을 전달하여 ReadOnlyCollection 인스턴스를 만들 수 있습니다. 이 아니라면 List의 생성자에 배열을 전달한 다음 목록에서 'AsReadOnly'를 호출하여 ReadOnlyCollection 인스턴스를 가져 와서 List를 만들 수 있습니다. –

0

배열의 개인 필드를 만든 다음 배열을 내부적으로 사용하기위한 액세스 방법을 만듭니다. 이 배열을 호출자에게 표시하여 열거 할 수 있도록 IEnumerable(Of T) 유형의 속성을 노출해야합니다.

이 접근

은 배열의 복사본을 생성 할 필요가와 IEnumerable(Of T)로 것을 를 반환 할 수 있도록 영리한 호출자가 단순히 배열에 다시 IEnumerable(Of T) 캐스팅하고 수정할 수 있지만 같은 고장이 아닙니다. 이 모든 것은 분명히 당신이 이미 본 것 같은 명백한 성능 벌칙이 있습니다. 이것은 배열이 기본 데이터 구조로 사용될 때 발생할 수있는 많은 문제 중 하나 일뿐입니다.

+0

오. 그것을 사용하는 방법에 대한 더 많은 코드를 게시 할 수 있습니까? 또는 일부 기사의 샘플 사용? 도움이 될 것입니다. –

0

를 제공했다.코드 Reflector 통해 생성 - 내가 읽을 희망 :

Public Class Core 
    Public Sub AddEntry(ByVal Ent As Entry) 
     Me.entries.Add(Ent) 
    End Sub 

    Public Sub RemoveEntry(ByVal ID As String) 
     Dim pred As Predicate(Of Entry) = Function (ByVal entry As Entry) 
      Return (entry.Id = ID) 
     End Function 
     Me.entries.RemoveAll(pred) 
    End Sub 

    Public ReadOnly Property Entries As IEnumerable(Of Entry) 
     Get 
      Return Me.entries 
     End Get 
    End Property 

    Private entries As List(Of Entry) = New List(Of Entry) 
End Class 

참고 : 나는 물체를 당신이 추가됩니다 경우 배열 대신 List<Entry>를 사용하여 제거하는 것이 좋습니다 것 - 혹은 심지어 Dictionary<string, Entry>은 당신이 방법을 제공 그것을 사용합니다.

+0

일부 스마트 엉덩이는 List에 IEnumerable 속성을 캐스팅 한 다음 AddEntry/RemoveEntry 메서드를 사용하지 않고 해당 목록에서 개체를 추가/제거 할 수 있습니다. :) –

+0

물론입니다. 많은 추가 작업을 수행하지 않는 한 악의적 인 사용자가 기본 모음을 수정하는 것을 방지하는 것은 비현실적입니다. –

+0

다른 답변에서 제안 된 ReadOnly 기능은 어떻습니까? 악의적 인 사용자가 어딘지로 돌아갈 가능성이 있습니까? –