使用属性添加多个附件

Add multiple attachments using Properties

我创建这个 属性 是为了添加多个附件:

Private ReadOnly Index As Integer
Private mAttachments(1 To 10) As String
Private ReadOnly NewAttachment As String

Public Property AddAttachment() As String
    Get
        If Index >= 1 And Index <= UBound(mAttachments) Then
            AddAttachment = mAttachments(Index)
        End If
        Return mAttachments(Index)
    End Get

    Set
        If Index >= 1 And Index <= UBound(mAttachments) Then
            mAttachments(Index) = NewAttachment
        Else
            MessageBox.Show("Error")
        End If
    End Set
End Property

为了测试调用,我使用了这两个文件,但我收到的电子邮件没有附件。无法理解我可能做错了什么。

 mAttachments(0) = "C:\teste.txt"
 mAttachments(1) = "C:\teste2.txt"

您应该有一个专门的 class 来处理附件列表。

选项 1:
如果你想保留数组,你可以让这个工作重载索引 属性.

非索引属性returns数组的副本强制消费者使用你的属性改变值数组(因为返回了一个副本,所以任何更改都只会应用到副本,而不是处理错误的原始数组)。

m_MaxAttachments 字段不是绝对必要的。您可以使用 Array.Length.
您不能使用此设置直接用 List(Of String) 替换数组。

Private ReadOnly m_MaxAttachments As Integer = 10
Private ReadOnly m_Attachments(m_MaxAttachments - 1) As String

Public ReadOnly Property MaxAttachments As Integer = m_MaxAttachments

Public ReadOnly Property Attachments As String()
    Get
        Return m_Attachments.Select(Function(s) s).ToArray()
    End Get
End Property

Public Property Attachments(index As Integer) As String
    Get
        If index < 0 OrElse index >= m_MaxAttachments Then
            AttachmentError(index)
            Return String.Empty
        End If
        Return m_Attachments(index)
    End Get
    Set
        If index >= 0 AndAlso index < m_MaxAttachments Then
            m_Attachments(index) = Value
        Else
            AttachmentError(index)
        End If
    End Set
End Property

Private Sub AttachmentError(value As Integer)
    MessageBox.Show($"Index out of range: {value} Valid range: [0, {m_MaxAttachments - 1}]")
End Sub

现在您可以使用索引器 Get/Set 值 from/to 底层字符串数组或使用非索引 属性 迭代集合的副本。例如:

Attachments(0) = "[Some Path]"
Attachments(1) = "[Other Path]"
Attachments(10) = "[10th Path]" '<- A MessageBox informs that the index is out of range

选项 2:
使用 Class 对象来处理 List(Of String) 并让 Public 属性 充当中介。
class 暴露了允许 add/remove/iterate 的方法(最后一个留给你,如果需要实现;重载索引 属性,移动到 class,只有 returns 一个 ReadonlyCollection 或索引值)。

Imports System.Collections.ObjectModel

Private ReadOnly Property m_Attachments As MyAttachments = New MyAttachments()

Public ReadOnly Property Attachments As MyAttachments
    Get
        Return m_Attachments
    End Get
End Property

Public Property Attachments(index As Integer) As String
    Get
        Return m_Attachments.Values(index)
    End Get
    Set
        If index >= 0 AndAlso index < MyAttachments.MaxAttachments Then
            m_Attachments.Values(index) = Value
        End If
    End Set
End Property

所以你可以这样写:

Attachments.Add("Some Path 1")
Attachments.Add("Some Path 2")
Attachments.Add("Some Path 3")

Attachments.Clear()
Attachments.Add("New Path")

' If you add more items than the max Capacity, it will return 
' the number of strings added to the List
Dim Items Added = Attachments.AddRange([Some IEnumerable(Of String)])

Attachments.Remove("New Path")
Attachments.RemoveAt(0)

等等。

处理程序Class:

Public Class MyAttachments
    Private Shared ReadOnly m_MaxCount As Integer = 10
    Private ReadOnly m_Values As New List(Of String)(m_MaxCount)

    Public Shared ReadOnly Property MaxAttachments As Integer = m_MaxCount

    Public ReadOnly Property Values As ReadOnlyCollection(Of String)
        Get
            Return m_Values.AsReadOnly()
        End Get
    End Property

    Public Property Values(index As Integer) As String
        Get
            Return m_Values(index)
        End Get
        Set
            If index >= 0 AndAlso index < MaxAttachments Then
                m_Values(index) = Value
            End If
        End Set
    End Property

    Public Sub Add(value As String)
        If m_Values.Count < m_Values.Capacity Then
            m_Values.Add(value)
        End If
    End Sub

    Public Function AddRange(values As IEnumerable(Of String)) As Integer
        Dim startItemsCount = m_Values.Count
        Dim indexer = startItemsCount
        For Each value As String In values
            If indexer >= m_MaxCount Then Exit For
            Add(value)
            indexer += 1
        Next
        Return indexer - startItemsCount
    End Function

    Public Sub Remove(value As String)
        m_Values.Remove(value)
    End Sub

    Public Sub RemoveAt(index As Integer)
        If index >= 0 AndAlso index < m_Values.Count Then
            m_Values.RemoveAt(index)
        End If
    End Sub
    Public Sub RemoveRange(indexes As Integer())
        For Each index As Integer In indexes
            RemoveAt(index)
        Next
    End Sub
    Public Sub RemoveRange(values As String())
        For Each value As String In values
            Remove(value)
        Next
    End Sub
    Public Sub Clear()
        m_Values.Clear()
    End Sub
    Public ReadOnly Property Count As Integer
        Get
            Return m_Values.Count
        End Get
    End Property
End Class